我写了 3 个类似的函数来找出 Go 指针反射的一个奇怪行为。package mainimport ( "reflect" "fmt")var i interface{} = struct {}{} // i is an interface which points to a structvar ptr *interface{} = &i // ptr is i's pointerfunc 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 个会 panic。为什么?3 的主要区别在于它创造了新价值。至于main2,我想ValueOf().Elem().Interface()已经重构了一个指向的接口struct{}{},只是不明白为什么会失败。
1 回答
哆啦的时光机
TA贡献1779条经验 获得超6个赞
从 reflect.ValueOf 返回的值包含存储在参数中的具体值。如果参数为 nil,则返回零 reflect.Value。
换句话说,reflect.Value 和传递给 reflect.Value 的接口具有相同的基础值。
如果您更改main1
为:main2
f
func f(x interface{}) { // print x's underlying value fmt.Println(reflect.ValueOf(x)) }
f
in的参数main3
是一个*struct{}
. 该函数f
取消引用指针(通过调用 Elem())并打印struct{}
.
可能令人困惑的一点是,reflect.ValueOf(ptr).Elem().Elem().Interface()
andreflect.ValueOf(ptr).Elem().Interface()
返回一个具有相同具体值的接口。
表达式reflect.ValueOf(ptr).Elem()
是 对应的反射值i
。对该值的调用Interface()
返回一个具有具体值的接口i
。
表达式是对应于具体值的reflect.ValueOf(ptr).Elem().Elem()
反映值。对该值的i
调用返回一个包含该具体值的接口。Interface()
- 1 回答
- 0 关注
- 107 浏览
添加回答
举报
0/150
提交
取消