go - 在反射中设置结构的值时遇到问题
问题描述
假设我有一个由其他两个组合而成的基本结构:
type Config struct {
common.Config
common.ServerConfig
APIPath string `type:"string" name:"apipath" default:"localhost:8443" desc:"Path to the gRPC API server"`
ServePath string `type:"string" name:"servepath" default:"/" desc:"Path to serve the API from"`
Organization string `type:"string" name:"organization" default:"" desc:"Default organization name"`
}
我想遍历结构中的每个字段并将值拉入结构中:
func NewConfig(c Configer) {
setConfigFlags(reflect.TypeOf(c).Elem(), c.GetViper())
}
所以我会这样称呼它:
conf := Config{}
common.NewConfig(&conf)
我的 setConfigFlags 正在做一些递归:
func setConfigFlags(t reflect.Type, viper *viper.Viper) {
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
switch field.Type.Kind() {
case reflect.Struct:
setConfigFlags(field.Type, viper)
continue
case reflect.String:
fieldValue := reflect.ValueOf(&field).Elem()
if !fieldValue.IsValid() || !fieldValue.CanSet() {
return
}
fieldValue.SetString(
viper.GetString(field.Tag.Get("name")),
)
}
}
}
现在,一旦我将 SetString 线打到底部,我就会收到此错误:
panic: reflect: call of reflect.Value.SetString on struct Value
当我当时查看 fieldValue 的类型时,它是一个 structfield。我在尝试解决该值并更改该字段的值时遇到了麻烦。我相信我没有正确获取实际结构字段的地址。示例和文档肯定没有帮助。
在这个特定的示例中,我正在提取 viper 值。基本上寻找一种通过结构标签定义我的毒蛇定义的方法,这是最终目标。
解决方案
正如 mkopriva 的评论所指出的那样,该代码正试图在一个类型上设置一个值。使用一个值。
func setConfigFlags(v reflect.Value, viper *viper.Viper) {
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
switch field.Type.Kind() {
case reflect.Struct:
setConfigFlags(v.Field(i), viper)
continue
case reflect.String:
v.Field(i).SetString(viper.GetString(field.Tag.Get("name")))
}
}
}
像这样称呼它:
func NewConfig(c Configer) {
setConfigFlags(reflect.Value(c).Elem(), c.GetViper())
}
推荐阅读
- python - 了解 dataframe.shape df.shape
- java - 尝试通过 Selenium 和 Java 使用 sendKeys 时获取验证消息
- java - 字符之间的Java有损XOR
- c# - C# IsMDIParent 容器 LabVIEW
- javascript - 在Javascript中使用indexOf将变量类型号与数组进行比较
- java - 如何从另一个类 JAVA 访问变量
- c - 使用 gtk2 创建和存储图像?
- python - 使用多个查询对 Python 中的数据框进行子集化
- android - android studio profiler 奇怪字符中的阿拉伯字母响应
- python - 根据 Pandas 中的时间戳分组生成值