reflect.New返回而不是初始化的结构体。

huangapple go评论81阅读模式
英文:

reflect.New returns <nil> instead of initialized struct

问题

我正在使用反射来构建一个库,但是关于reflect.New我有一个不明白的地方。

type A struct {
	A int
	B string
}

func main() {

	real := new(A)
	reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
	fmt.Println(real)
	fmt.Println(reflected)
}

输出结果为:

&amp;{0 }
&lt;nil&gt;

难道reflect.New也应该返回&amp;{0 }吗?(可运行版本

最终,我希望能够遍历反射结构体的字段(reflected.NumField()返回reflected.NumField undefined (type interface {} is interface with no methods)),并使用SetIntSetString等方法。

谢谢。

英文:

I am using reflection for a library I'm building but there's something I don't understand about reflect.New.

type A struct {
	A int
	B string
}

func main() {

	real := new(A)
	reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
	fmt.Println(real)
	fmt.Println(reflected)
}

Gives:

$ go run *go
&amp;{0 }
&lt;nil&gt;

Isn't reflect.New supposed to return &amp;{0 } too? (Runnable Version)

Ultimately, I wish to be able to iterate over the fields of the reflected struct (reflected.NumField() gives reflected.NumField undefined (type interface {} is interface with no methods)) and use SetInt, SetString and so on.

Thanks,

答案1

得分: 7

你在创建real变量时使用了内置的new()函数,它返回一个指针!real的类型是*A,而不是A!这就是混淆的根源。

reflect.New()返回给定类型的(零值)的指针(包装在reflect.Value中)。如果传递类型A,你会得到一个包装的*AA被初始化/清零。如果传递类型*A,你会得到一个包装的**A*A被初始化(清零),而任何指针类型的零值都是nil

你基本上要求reflect.New()创建一个指针类型(*A)的新值,而且正如前面提到的,它的零值是nil

你必须传递类型A(而不是类型*A)。可以这样使用(在Go Playground上尝试一下):

real := new(A)
reflected := reflect.New(reflect.TypeOf(real).Elem()).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)

或者这样使用(Go Playground):

real := A{}
reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)
英文:

You used the builtin new() function when you created your real variable, which returns a pointer! Type of real is *A, not A! This is the source of the confusion.

reflect.New() returns a pointer to the (zeroed) value of the given type (wrapped in a reflect.Value). If you pass the type A, you get back a wrapped *A, A initialized / zeroed. If you pass the type *A, you get back a wrapped **A, *A initialized (zeroed), and the zero value for any pointer type is nil.

You basically ask reflect.New() to create a new value of a pointer type (*A), and –as mentioned– its zero value is nil.

You have to pass the type A (and not the type *A). It works like this (try it on the Go Playground):

real := new(A)
reflected := reflect.New(reflect.TypeOf(real).Elem()).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)

Or like this (Go Playground):

real := A{}
reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)

huangapple
  • 本文由 发表于 2017年3月28日 22:35:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/43072451.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定