首页 > 解决方案 > 如何通过struct的fieldName获取值

问题描述

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)
}

我可以通过反射来获取基于字段名称的值吗?

标签: gostructreflect

解决方案


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. 检查传递的值是否为结构或字段存在是否被省略。

/我用切片表达式切断了路径的前导:path[1:]所以我们不必处理循环内的空字段名称。

以上getValue()将结果作为interface{}. 如果你需要IDas 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上试试这个。


推荐阅读