在有些场景下,我们需要用一个map[string]interface{}, map的key是struct中的一个tag的值, value是需要赋值的值,我们可以使用reflect包来进行操作。
- 我们需要struct的指针,只有指针我们才能在函数中改变struct的值
- 根据指针获取struct的实例,Type
- 依次遍历struct的域,取出域中的tag和map中的key进行比较,然后比较域的Type和map中value的Type,如果相等就可以进行赋值了
贴代码:
func SetValueByTag(result interface{}, tagName string, tagMap map[string]interface{}) error {
t := reflect.TypeOf(result)
if t.Name() != "" {
return fmt.Errorf("result have to be a point")
}
v := reflect.ValueOf(result).Elem()
t = v.Type()
fieldNum := v.NumField()
for i := 0; i < fieldNum; i++ {
fieldInfo := t.Field(i)
tag := fieldInfo.Tag.Get(tagName)
if tag == "" {
continue
}
if value, ok := tagMap[tag]; ok {
if reflect.ValueOf(value).Type() == v.FieldByName(fieldInfo.Name).Type() {
v.FieldByName(fieldInfo.Name).Set(reflect.ValueOf(value))
}
}
}
return nil
}