我写了 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{}) { // 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{}{},只是不明白为什么会失败。
哆啦的时光机
相关分类