如何通过结构的fieldName获取值

时间:2019-04-15 07:56:10

标签: go struct reflect

type mcat struct {
    ID int
}
type cat struct {
    Name string
    M    mcat
}

func getValue(path string, mcat cat){
    //throuth struct path get the value
}

func main(){
    mycat := cat{"cat", mcat{1}}
    id := getvalue("/M/ID", mycat)
}

我可以通过反映以基于字段名称的值来做到这一点吗?

1 个答案:

答案 0 :(得分:0)

您可以使用Value.FieldByName()函数来完成您想做的事情。只需在路径中可以使用strings.Split()进行拆分的部分范围内即可。

这是一个例子:

func getValue(i interface{}, path string) interface{} {
    v := reflect.ValueOf(i)
    for _, field := range strings.Split(path[1:], "/") {
        v = v.FieldByName(field)
    }
    return v.Interface()
}

func main() {
    mycat := cat{"cat", mcat{1}}
    id := getValue(mycat, "/M/ID")
    fmt.Println(id)
}

它输出(在Go Playground上尝试):

1

一些注意事项:

以上解决方案适用于所有结构类型,而不仅适用于cat。检查传递的值是否为struct或字段是否存在。

我使用切片表达式/剪切了路径的开头path[1:],因此我们不必在循环内处理空字段名称。

上面的getValue()interface{}的形式返回结果。如果您需要ID作为int,则可以使用如下类型的断言:

var intID int
intID = id.(int)

还要注意,对路径使用可变参数可能会更好/更有用:

func getValue(i interface{}, path ...string) interface{} {
    v := reflect.ValueOf(i)
    for _, field := range path {
        v = v.FieldByName(field)
    }
    return v.Interface()
}

func main() {
    mycat := cat{"cat", mcat{1}}
    id := getValue(mycat, "M", "ID")
    fmt.Println(id)
}

输出是相同的。在Go Playground上尝试这个。