go - 在 Go 中获取子结构字段

标签 go struct

我正在尝试使用反射从 struct 值中获取字段。

package main

import (
    "fmt"
    "reflect"
)

type Vertex struct {
    X         string
    Y         string
    SubVertex SubVertex
}
type SubVertex struct {
    Z string
}

func get_field(v Vertex, field string) string {
    r := reflect.ValueOf(v)
    f := reflect.Indirect(r).FieldByName(field)
    return f.String()
}

func main() {
    v := Vertex{"a", "b", SubVertex{"c"}}

    fmt.Println(get_field(v, "X"))
    fmt.Println(get_field(v, "Y"))
    fmt.Println(get_field(v, "Z"))  // Invalid Value
}

在第三种情况下,当我尝试获取 Z 字段的值时,我得到了 Invalid Value。如果 SubVertex 是匿名字段,这会起作用,但我需要使用命名字段。

我如何使它工作?

最佳答案

在这种情况下,您必须以与正常访问值相同的方式使用反射包。所以

v.X // a
v.Y // b
v.SubVertex.Z // c

成为

r := reflect.ValueOf(v)
x := reflect.Indirect(r).FieldByName("X")
x.String() // a
...
z := reflect.Indirect(r).FieldByName("SubVertex").FieldByName("Z")
z.String() // c

请注意,FieldByName() 是在 Value 上调用的,并返回一个 Value,因此它的工作原理与定期访问它非常相似.另请注意,根据文档:

Indirect returns the value that v points to. If v is a nil pointer, Indirect returns a zero Value. If v is not a pointer, Indirect returns v.

因此,对 Indirect() 的调用将是一个空操作,但如果您决定在未来给它一个指针,它将保护它免于崩溃。

至于你的功能,这行得通

func get_field(v Vertex, field string) string {
    r := reflect.ValueOf(v)
    if field == "Z" {
        f := reflect.Indirect(r).FieldByName("SubVertex").FieldByName(field)
        return f.String()
    }
    f := reflect.Indirect(r).FieldByName(field)

    return f.String()
}

https://play.golang.org/p/eZyTl8OSTZ

关于go - 在 Go 中获取子结构字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43074939/

相关文章:

c - 访问函数内动态分配的结构

c - 错误 : storage size of 'name' isn't known

docker - 我的管道不允许我通过 golang 连接,尽管它可以在开发环境中工作

go - 所有的 goroutines 都睡着了——僵局!与 WaitGroup

pointers - 如何将不同的错误接口(interface)实现存储在一起,然后在 Go 中使用它们进行类型比较?

c - ty如何像数组一样定义可通过下标访问的结构体 union ?就像在 GLSL 中一样

c - 在 OpenMP 中将结构体指针定义为 threadprivate

ios - 创建结构的空数组给我一个错误

go - 如何在 Golang 中访问嵌套的 Json 键值

go - 具有相似元素类型的 slice 之间的转换