基本上,迭代struct
的字段值的唯一方法(据我所知)如下所示:
type Example struct {
a_number uint32
a_string string
}
//...
r := &Example{(2 << 31) - 1, "...."}:
for _, d:= range []interface{}{ r.a_number, r.a_string, } {
//do something with the d
}
我想知道,是否有更好、更通用的方法来实现[]interface{}{ r.a_number, r.a_string, }
,这样我就不需要单独列出每个参数,或者,是否有更好的方法来循环通过一个结构体?
我试图查看reflect
包,但遇到了障碍,因为我不确定检索reflect.ValueOf(*r).Field(0)
后该怎么做。
谢谢!
8条答案
按热度按时间kulphzqa1#
在使用
Field(i)
获取字段的reflect.Value
之后,可以通过调用Interface()
从reflect.Value
获取一个接口值,该接口值表示字段的值。没有函数可以将字段的值转换为具体的类型,正如你所知,go中没有泛型,因此没有签名为
GetValue() T
的函数,T
是该字段的类型(当然,根据字段的不同,类型也会变化)。在go中你能达到的最接近的是
GetValue() interface{}
,而这正是reflect.Value.Interface()
所提供的。下面的代码说明如何使用反射(play)获取结构体中每个导出字段的值:
vvppvyoh2#
如果你想迭代一个结构体的字段和值,你可以参考下面的Go语言代码。
在playground中运行
**注意:**如果未导出结构体中的字段,则
v.Field(i).Interface()
将给予异常panic: reflect.Value.Interface: cannot return value obtained from unexported field or method.
ni65a41a3#
Go 1.17(2021年第三季度)应该会增加一个新的选项,通过commit 009bfea和CL 281233,修复issue 42782。
反映:添加可见字段函数
当编写在结构类型上反射的代码时,通常需要知道结构字段的完整集合,包括由于嵌入匿名成员而可用的字段,同时排除由于与另一个同名字段处于同一级别而被擦除的字段。
这样做的逻辑并不复杂,但有点微妙,很容易出错。
此CL向
reflect
包添加了一个新的reflect.VisibleFields()
函数,该函数返回适用于给定结构类型的有效字段的完整集合。例如,
6fe3ivhb4#
也许太晚了:)))但是还有另一种解决方案,你可以找到结构体的键和值,然后迭代它们
piok6c0g5#
使用此:
====〉10
====〉5
4uqofj5v6#
采用Chetan Kumar解决方案,如果您需要申请
map[string]int
lvjbypge7#
使用
reflect
包,首先用reflect.TypeOf
得到变量的类型,用reflect.NumField
得到元素的个数,要迭代得到一个结构的字段的值,必须反映变量,使用函数rg.Elem().Field(i)
9nvpjoqh8#
要迭代Struct,您可以先将其追加到Slice。
就像这个例子:
Go Playground link
输出: