go - 如何通过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)
}
我可以通过反射来获取基于字段名称的值吗?
解决方案
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{}
. 如果你需要ID
as 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上试试这个。
推荐阅读
- excel - 查找单元格上方的单元格的值
- reactjs - React js中Material-ui Pickers的日期格式没有改变
- php - 在 laravel 中无法检查包含点的 GET 参数
- laravel - 在刀片组件中获取 Alpine JS 值?
- c# - 带有密码的 RSA 密钥对(AES-128-CBC 或 AES-256-CBC)
- java - 在firestore中获取查询结果的任何其他方法?
- excel - 尝试从 A 到 Z 对 Listbox 中加载的列进行排序
- graphql - 当返回类型是数组时,如何将父数据的父数据传递给子解析器?
- python - 如何将 for 循环与条件相结合?
- ansible - ansible playbook 卡在特定类型的主机上