为了账号安全,请及时绑定邮箱和手机立即绑定

接口指针的奇怪行为

接口指针的奇怪行为

Go
慕容3067478 2023-05-15 09:43:36
我写了 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为:main2f

func f(x interface{}) {             // print x's underlying value
    fmt.Println(reflect.ValueOf(x))
}

fin的参数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()


查看完整回答
反对 回复 2023-05-15
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信