获取空指针类型的 reflect.Value。

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

Get reflect.Value of nil pointer type

问题

使用Go的reflect包,我想要获取特定类型的nil指针,例如,我想要一个表示*int类型且值为nil而不是*0reflect.Value

目前我通过以下方式获取零值,但这是*0而不是nil

// varType是reflect.Type类型
reflect.New(reflect.PtrTo(varType).Elem())

这将给我一个零值,例如*int*0

但我无法弄清楚如何获取一个类型为*int且为nil而不是*0reflect.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中)。因此,如果传递*intreflect.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(&quot;Type: %T, Value: %v\n&quot;, v, v)

if p, ok := v.(*int); ok {
	fmt.Println(&quot;v holds *int, its value is:&quot;, p)
}

Output (try it on the Go Playground):

Type: *int, Value: &lt;nil&gt;
v holds *int, its value is: &lt;nil&gt;

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

huangapple
  • 本文由 发表于 2023年3月27日 21:39:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75856460.html
匿名

发表评论

匿名网友

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

确定