当前位置: 首页 > 面试题库 >

Reflect认为struct值也是ptr吗?

丁茂
2023-03-14
问题内容

我有一个像这个演示这样的数据结构。如您所见,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()被认为是a
reflect.Struct,但是如果我尝试通过使用将其视为结构.FieldByName("S"),它会慌张,因为它认为v是a ptr

因此,如果我尝试ptr通过调用将其视为“ a” .Elem(),则会感到恐慌,因为它认为v是“ a” struct

我已经尝试了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语言中,不需要显式指针取消引用,但这是我的意思)。现在的问题是:如果更改,v.FieldByName("bar")为什么会给出错误?相同的原因。

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

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



 类似资料:
  • 描述 (Description) C库函数void free(void *ptr)释放先前通过调用calloc,malloc或realloc分配的内存。 声明 (Declaration) 以下是free()函数的声明。 void free(void *ptr) 参数 (Parameters) ptr - 这是指向先前分配有要释放的malloc,calloc或realloc的内存块的指针。 如果将

  • import "reflect" reflect包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函数返回一个Type类型值。调用ValueOf函数返回一个Value类型值,该值代表运行时的数据。Zero接受一个Type类型参数并返回一个代表该类型零值的Value类型值。 参见"The Laws of R

  • 为什么这个字符串是数字的?那些字符代表什么?

  • 问题内容: 我有一个像这个演示这样的数据结构。 和代码: 当我不为家庭使用Point时,它会返回“ bari”并且没关系。但是有了point,就会出现此错误。 反射:在ptr值上调用reflect.Value.FieldByName 我进行了很多搜索,但找不到答案可以提供帮助。 问题答案: 您已经注意到,是。正如错误所言,您不能在该值是指针的地方调用。 相反,您需要间接指针,以获取其指向的值,然后

  • 首先,我的声明是: 我的主要活动获取编号和文本: 我的Activity2应该得到数字和文本: 文本很受欢迎,但数值始终为0。

  • fest-reflect为java库提供了一个接口,简化了使用反射,从而提高了可读性和类型安全。