我正在尝试使用反射从 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()
}
关于go - 在 Go 中获取子结构字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43074939/