为了账号安全,请及时绑定邮箱和手机立即绑定

反射结构字段。使用标志指针值设置

反射结构字段。使用标志指针值设置

Go
RISEBY 2022-06-21 16:51:17
我解析了一堆标志,然后尝试将这些值分配给结构中的字段,但是我很难将解析的标志值设置到结构中,因为我无法键入断言或强制转换它.这是我拥有的代码片段。过分担心IterFields函数并不重要,基本上结构中的每个字段都会调用第三个参数...注意:下面的代码中有注释突出显示错误。    flag.Parse()    IterFields(st, v, func(field reflect.Value, sf reflect.StructField) {        flag.VisitAll(func(f *flag.Flag) {            if f.Name == strings.ToLower(sf.Name) || f.Name == sf.Tag.Get("short") {                fmt.Printf("%+v, %T\n", f.Value, f.Value)                // PRINTS: true, *flag.boolValue                                if v, ok := f.Value.(bool); ok {                    fmt.Println("ok")                } else {                    fmt.Println("not ok")                }                // ERROR: impossible type assertion: bool does not implement flag.Value (missing Set method)                                field.Set(reflect.ValueOf(f.Value))                // PANIC: value of type *flag.boolValue is not assignable to type bool            }        })    })
查看完整描述

1 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

f.Valueflag.Value是一种抽象各种标志值的接口类型。正如您的代码所示,它不是类型bool,而是一些 non-exported *flag.boolValue。你不应该关心它的动态类型。

您可以使用该Value.String()方法将其值作为 a 来获取string,这将是"false"或者"true"对于 bool 类型,您可以使用简单的比较来从中获取boolf.Value.String() == "true"

但更好的方法是:flag.Value来自flag包的所有值也都实现flag.Getter,它也有一个Get()方法,可以bool在布尔标志的情况下直接返回一个值(interface{}当然包装在里面)。只需使用它:

field.Set(reflect.ValueOf(f.Value.(flag.Getter).Get()))

以上适用于任何类型的字段(假设标志的值类型可分配给字段的类型)。

仅对于bool字段,或者您也可以使用:

field.SetBool(f.Value.(flag.Getter).Get().(bool))


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信