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

我解析了一堆标志,然后尝试将这些值分配给结构中的字段,但是我很难将解析的标志值设置到结构中,因为我无法键入断言或强制转换它.


这是我拥有的代码片段。过分担心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

            }

        })

    })


RISEBY
浏览 110回答 1
1回答

梵蒂冈之花

f.Valueflag.Value是一种抽象各种标志值的接口类型。正如您的代码所示,它不是类型bool,而是一些 non-exported *flag.boolValue。你不应该关心它的动态类型。您可以使用该Value.String()方法将其值作为 a 来获取string,这将是"false"或者"true"对于 bool 类型,您可以使用简单的比较来从中获取boola f.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))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go