gpt4 book ai didi

reflection - Reflect 认为 struct Value 也是一个 ptr?

转载 作者:IT王子 更新时间:2023-10-29 00:54:32 38 4
gpt4 key购买 nike

我有一个类似这个演示的数据结构。如您所见,foo 有一个指向 bar 的嵌入式指针:

type foo struct {
*bar
}

type bar struct {
S []byte
}

我正在像这样使用 reflect 包:

func test(x interface{}) {

var v = reflect.ValueOf(x)

if v.Kind() == reflect.Struct {
fmt.Println("was a struct")

// panic: reflect: call of reflect.Value.Elem on struct Value
// v = v.Elem()

// panic: reflect: call of reflect.Value.Field on ptr Value
v = v.FieldByName("S")
}
}

func main() {
var f foo
test(f)
fmt.Println(string(f.S))
}

因此 v.Kind() 被识别为 reflect.Struct,但是如果我尝试使用 .FieldByName("S"),它会 panic ,因为它认为 v 是一个 ptr

因此,如果我尝试通过调用 .Elem() 将其视为 ptr,它会 panic ,因为它认为 v 是一个结构

我试过 reflect.Indirect() 以及其他一些方法,但我不知道如何获取嵌入式指针的字段。

有没有办法从指向结构的嵌入式指针获取 reflect.Value 表示?

演示: http://play.golang.org/p/n0eea6XW3I


编辑: 还尝试了 v = v.FieldByName("bar"),但得到:

panic: runtime error: invalid memory address or nil pointer dereference

最佳答案

我们首先需要了解的是 var f foo 这行等同于 f := foo{}。这会将内部字段 bar(*bar 类型)初始化为其零值...nil。嵌入类型和反射的行为似乎是它将嵌入类型的字段视为类型本身的字段。因此,当您请求 v.FieldByName("S") 时,它试图在 f 的成员 bar 中找到该字段,该字段为 nil。

您正在尝试执行此操作 (*f.bar).S。 (在 Go 中不需要显式指针取消引用,但它说明了我的观点)。现在的问题是:如果将 is 更改为 v.FieldByName("bar") 为什么会出错?同样的原因。

仔细查看堆栈跟踪,FieldByName 行不再崩溃,崩溃的行是 fmt.Println(string(f.S))。同样,从语义上讲,您正在执行 (*f.bar).S。但是成员“bar”是 nil,所以实际上,您是在执行 nil 指针取消引用。

您可以通过将 var f foo 更改为 f := foo{&bar{}} 来修复这两个错误。

关于reflection - Reflect 认为 struct Value 也是一个 ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22085485/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com