Go 接口指针的奇怪行为
我编写了3个类似的函数来找出Go指针反射的奇怪行为Go 接口指针的奇怪行为,go,reflection,interface,go-reflect,Go,Reflection,Interface,Go Reflect,我编写了3个类似的函数来找出Go指针反射的奇怪行为 package main import ( "reflect" "fmt" ) var i interface{} = struct {}{} // i is an interface which points to a struct var ptr *interface{} = &i // ptr is i's pointer func f(x interface{}) {
package main
import (
"reflect"
"fmt"
)
var i interface{} = struct {}{} // i is an interface which points to a struct
var ptr *interface{} = &i // ptr is i's pointer
func f(x interface{}) { // print x's underlying value
fmt.Println(reflect.ValueOf(x).Elem())
}
func main1() { // f is asking for interface? OK, I'll use the struct's interface
structValue := reflect.ValueOf(ptr).Elem().Elem().Interface()
f(structValue)
}
func main2() { // Error? Let me try the struct's pointer
structPtr := reflect.ValueOf(ptr).Elem().Interface()
f(structPtr)
}
func main3() { // Why this one could succeed after New() ?
typ := reflect.ValueOf(ptr).Elem().Elem().Type()
newPtr := reflect.New(typ).Elem().Addr().Interface()
f(newPtr)
}
func main() {
//main1() // panic: reflect: call of reflect.Value.Elem on struct Value
//main2() // panic: reflect: call of reflect.Value.Elem on struct Value
main3() // OK. WHY???
}
只有main3在工作,其他2个会惊慌失措。为什么?
3的关键区别在于它创建了一个新值
至于main2,我认为
ValueOf().Elem().Interface()
已经重建了一个指向struct{}{}
的接口,只是不理解它为什么会失败。从reflect.ValueOf返回的值保存了参数中存储的具体值。如果参数为nil,则返回零reflect.Value
换句话说,reflect.Value和传递给reflect.Value的接口具有相同的基础值
如果将f
更改为:
func f(x interface{}) { // print x's underlying value
fmt.Println(reflect.ValueOf(x))
}
main3
中f
的参数是*结构{}
。函数f
取消对指针的引用(调用Elem()),并打印结构{}
的反射值
有一点可能令人困惑,那就是reflect.ValueOf(ptr).Elem().Elem().Interface()
和reflect.ValueOf(ptr).Elem().Interface()
返回具有相同具体值的接口
表达式reflect.ValueOf(ptr.Elem()
是对应于i
的反射值。对该值调用Interface()
将返回一个带有i
中具体值的接口
表达式
reflect.ValueOf(ptr.Elem().Elem()
是与i
的具体值相对应的反射值。对该值调用Interface()
将返回一个包含该具体值的接口。我编写main1和main2的原因是我认为Interface{}
是一种特殊的指针。或者,是不是在戈朗?因此,接口应该能够通过ValueOf().Elem()调用。。。