英文:
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)
}
输出结果为:
&{0 }
<nil>
难道reflect.New
也应该返回&{0 }
吗?(可运行版本)
最终,我希望能够遍历反射结构体的字段(reflected.NumField()
返回reflected.NumField undefined (type interface {} is interface with no methods)
),并使用SetInt
、SetString
等方法。
谢谢。
英文:
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
&{0 }
<nil>
Isn't reflect.New
supposed to return &{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
,你会得到一个包装的*A
,A
被初始化/清零。如果传递类型*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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论