pointers - 反射结构字段。使用标志指针值设置
问题描述
我解析了一堆标志,然后尝试将这些值分配给结构中的字段,但是我很难将解析的标志值设置到结构中,因为我无法键入断言或强制转换它.
这是我拥有的代码片段。过分担心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
}
})
})
解决方案
f.Value
flag.Value
是一种抽象各种标志值的接口类型。正如您的代码所示,它不是类型bool
,而是一些 non-exported *flag.boolValue
。你不应该关心它的动态类型。
You may use the Value.String()
method to get its value as a string
, which will be either "false"
or "true"
for bool types, you may use simple comparison to obtain a bool
from it like f.Value.String() == "true"
.
But a better approach would be: all flag.Value
values originating from the flag
package also implement flag.Getter
which also has a Get()
method that will directly return a bool
value in case of a bool flag (wrapped in interface{}
of course). Just use that:
field.Set(reflect.ValueOf(f.Value.(flag.Getter).Get()))
The above works for fields of any type (given that the flag's value type is assignable to the field's type).
For bool
fields only, alternatively you may also use:
field.SetBool(f.Value.(flag.Getter).Get().(bool))
推荐阅读
- r - CVXR:无法识别凸函数
- jupyter-notebook - 如何从当前笔记本中的另一个笔记本执行单元格 1
- c++ - 无法使用 platformio 在库中包含 i2s.h
- c++ - 在 C++ 中覆盖 == 运算符
- docker - 如何使用 kubernetes 启动停止的容器?
- terraform - 在 Terraform 远程后端使用变量
- regex - 正则表达式查找某些字符之间的匹配并包含特定字符
- c++ - cmake target_link_libraries() 无法通过 set_target_properties(archive_output_name) 找到重命名的 lib 目标
- javascript - JavaScript 在本地设置时无法正常运行
- .net-core - 如何在 .NET Core 中实现进程间通信?