英文:
Get reflect.Value of nil pointer type
问题
使用Go的reflect包,我想要获取特定类型的nil指针,例如,我想要一个表示*int类型且值为nil而不是*0的reflect.Value。
目前我通过以下方式获取零值,但这是*0而不是nil:
// varType是reflect.Type类型
reflect.New(reflect.PtrTo(varType).Elem())
这将给我一个零值,例如*int的*0。
但我无法弄清楚如何获取一个类型为*int且为nil而不是*0的reflect.Value。
我理解为什么.Set(reflect.ValueOf(nil))不起作用。也许我错过了一个关键步骤?
英文:
Using the Go reflect package I'd like to get a nil pointer of a particular type, for example I'd like a reflect.Value that represents *int with a value of nil not *0
I'm currently getting the zeroed value like this but this is *0 not nil
// varType is a reflect.Type
reflect.New(reflect.PtrTo(varType).Elem())
Will give me a zero value, e.g. *0 for *int
But what I can't quite workout is now to get a reflect.Value of say type *int and it be nil not *0
I understand why .Set(reflect.ValueOf(nil)) does not work. Perhaps I've missed a crucial step?
答案1
得分: 2
使用reflect.Zero()代替reflect.New()。reflect.New()会为给定类型分配一个值,并返回指向该值的指针(封装在reflect.Value中)。
reflect.Zero()不会分配新值,它返回给定类型的零值(封装在reflect.Value中)。因此,如果传递*int的reflect.Type描述符,或者任何其他指针类型,由于指针类型的零值是nil,你将得到一个nil指针。
例如:
var i int
varType := reflect.TypeOf(i)
v := reflect.Zero(reflect.PtrTo(varType)).Interface()
fmt.Printf("Type: %T, Value: %v\n", v, v)
if p, ok := v.(*int); ok {
fmt.Println("v holds *int, its value is:", p)
}
输出结果(在Go Playground上尝试):
Type: *int, Value: <nil>
v holds *int, its value is: <nil>
请注意,你必须调用Value.Interface()从reflect.Value中获取一个值(离开反射世界)。还要注意,返回的接口值(类型为interface{}或any)不会是nil,但它包含一个*int类型和一个nil指针值。有关详细信息,请参阅https://stackoverflow.com/questions/29138591/hiding-nil-values-understanding-why-go-fails-here/29138676#29138676
英文:
Use reflect.Zero() instead of reflect.New(). reflect.New() allocates a value of the given type, and returns a pointer to it (wrapped in reflect.Value).
reflect.Zero() does not allocate a new value, it returns the zero value of the given type (wrapped in reflect.Value). So if you pass the reflect.Type descriptor of *int, or any other pointer type, since the zero value for pointer types is nil, you get back a nil pointer.
For example:
var i int
varType := reflect.TypeOf(i)
v := reflect.Zero(reflect.PtrTo(varType)).Interface()
fmt.Printf("Type: %T, Value: %v\n", v, v)
if p, ok := v.(*int); ok {
fmt.Println("v holds *int, its value is:", p)
}
Output (try it on the Go Playground):
Type: *int, Value: <nil>
v holds *int, its value is: <nil>
Do note however that you have to call Value.Interface() to get a value out of reflect.Value (to leave the reflection world). Also note that this returned interface value (it has type interface{} or any) will not be nil, but it packs a *int type and a nil pointer value. For details, see https://stackoverflow.com/questions/29138591/hiding-nil-values-understanding-why-go-fails-here/29138676#29138676
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论