英文:
How to set struct fields throw interface?
问题
大家好!
我的任务是解析命令行参数并填充结构体字段。我的函数必须能处理各种类型的参数-它们将在结构体标签中描述。
例如:
type CommndLineArguments struct {
Configfile string `required:"false" name:"config" default:"/etc/daemon.conf" description:"配置文件"`
Daemon bool `required:"true" name:"daemon" default:"false" description:"作为守护进程运行"`
}
我使用reflect
和flag
包。像这样:
func GetArguments(variable interface{}) error {
//检查是否为指向结构体的指针
variableType := reflect.TypeOf(variable)
if variableType.Kind() != reflect.Ptr {
return errors.New(ERR_PASS_BY_VALUE)
} else if variableValue := variableType.Elem(); variableValue.Kind() != reflect.Struct {
return errors.New(ERR_NOT_A_STRUCT)
}
// 解析参数
variableValue := variableType.Elem()
for i := 0; i < variableValue.NumField(); i++ {
structField := variableValue.Field(i)
fieldName := structField.Name
fieldType := structField.Type
fieldTag := structField.Tag
现在我准备解析参数了。
switch fieldType.Kind() {
case reflect.Bool:
defaultValue, err := strconv.ParseBool(fieldTag.Get("default"))
if err != nil {
return errors.New(ERR_PARSE_ERROR + err.Error())
}
flag.BoolVar(&structField, fieldName, defaultValue, fieldTag.Get("description"))
但是我在最后一行遇到了一个错误。
./parser.go:42: cannot use &structField (type *reflect.StructField) as type *bool in function argument
我的问题是如何正确设置这个字段?
英文:
everyone!
My task is to parse command-line argument and fill struct fields. And my function must works with all kinds of arguments - they'll describe in struct tag.
For example:
type CommndLineArguments struct {
Configfile string `required:"false" name:"config" default:"/etc/daemon.conf" description:"Config file"`
Daemon bool `required:"true" name:"daemon" default:"false" description:"Run as daemon"`
}
I use reflect
and flag
packages. Like this:
func GetArguments(variable interface{}) error {
//Check is this a pointer to struct
variableType := reflect.TypeOf(variable)
if variableType.Kind() != reflect.Ptr {
return errors.New(ERR_PASS_BY_VALUE)
} else if variableValue := variableType.Elem(); variableValue.Kind() != reflect.Struct {
return errors.New(ERR_NOT_A_STRUCT)
}
// Parse parameters
variableValue := variableType.Elem()
for i := 0; i < variableValue.NumField(); i++ {
structField := variableValue.Field(i)
fieldName := structField.Name
fieldType := structField.Type
fieldTag := structField.Tag
Now I'm ready to parse arguments.
switch fieldType.Kind() {
case reflect.Bool:
defaultValue, err := strconv.ParseBool(fieldTag.Get("default"))
if err != nil {
return errors.New(ERR_PARSE_ERROR + err.Error())
}
flag.BoolVar(&structField, fieldName, defaultValue, fieldTag.Get("description"))
But I get an error in last line.
./parser.go:42: cannot use &structField (type *reflect.StructField) as type *bool in function argument
My question is how can I set this field correctly?
答案1
得分: 0
你需要获取字段的地址(也使用ValueOf
而不是TypeOf
):
flag.BoolVar(fld.Addr().Interface().(*bool), fieldName, defaultValue, fieldTag.Get("description"))
简单示例 @ http://play.golang.org/p/yEG-OH6d4W
英文:
You will have to get the address of the field (also use ValueOf
not TypeOf
):
flag.BoolVar(fld.Addr().Interface().(*bool), fieldName, defaultValue, fieldTag.Get("description"))
Simple demo @ http://play.golang.org/p/yEG-OH6d4W
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论