给定字段名称和值的映射,修改结构值

elh*_*ari 0 go

这是我的结构:

type TableFields struct {
    Name   string
    Family string
    Age    int
}

sample := TableFields{
    Name:   "bill",
    Family: "yami",
    Age:    25,
}
Run Code Online (Sandbox Code Playgroud)

这是我用来描述问题的非常简单的示例。

我想sample使用map接收到的键和值更改结构中的值。每次我收到的map键和值都会不同。如何使用map来编辑sample结构?

例如:

updateTheseFieldsWithTheseVals := make(map[string]string)
updateTheseFieldsWithTheseVals["family"] = "yamie"
// this is my way
for key,val := range updateTheseFieldsWithTheseVals {
    // sample.Family=yamie works, but is not the answer I am looking for
    // sample.key = val  *This solution is not possible*
    oldValue := reflect.Indirect(reflect.ValueOf(get)).FieldByName(key).String()
    fmt.Println(oldValue) // result is yami

    oldValue = val
    fmt.Println(oldValue) //result is yamie
}
fmt.Println(updateTheseFieldsWithTheseVals)
// result :
// {bill yami 25}
Run Code Online (Sandbox Code Playgroud)

这会运行,但不会更改中的值sample

Cer*_*món 5

这是一个按名称更新字符串字段的函数:

func update(v interface{}, updates map[string]string) {
    rv := reflect.ValueOf(v).Elem()
    for key, val := range updates {
        fv := rv.FieldByName(key)
        fv.SetString(val)
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

updates := map[string]string{"Family": "yamie"}
sample := TableFields{
    Name:   "bill",
    Family: "yami",
    Age:    25,
}
update(&sample, updates)
Run Code Online (Sandbox Code Playgroud)

操场的例子

有关该功能的一些注意事项:

  • update函数需要一个指针值,以便可以更新原始值。
  • 如果找不到该字段或该字段不是字符串类型,则该函数将出现紧急情况。根据功能的使用方式,为fv.IsValid()和添加检查可能会有所帮助fv.Kind() == reflect.String