Go反射批量赋值结构体字段需传入指针、确保字段导出且可寻址,遍历字段按名匹配map值并校验类型一致,支持嵌套与指针字段处理,推荐封装带错误提示的安全函数。
用 Go 的 reflect 批量给结构体字段赋值,核心是:先获取结构体指针的 reflect.Value,再遍历其字段,对可寻址且可设置的字段调用 Set()。关键在于类型匹配、地址合法性与导出性检查。
Go 反射只能修改导出(首字母大写)且可寻址的字段。若传入非指针或结构体字面量,CanAddr() 和 CanSet() 会返回 false,直接调用 Set() 会 panic。
&struct{},不能传 struct{}
Name),小写字段(如 name)无法被反射设置v := reflect.ValueOf(ptr).Elem() 获取可操作的结构体值常见做法是用 map[string]interface{} 或切片按顺序提供新值。推荐按字段名匹配更安全:
v.NumField(),用 v.Type().Field(i).Name 拿字段名v.Field(i).Set(reflect.ValueOf(val))
int,map 中对应值也得是 int,否则 Set() 报错reflect.TypeOf(val).ConvertibleTo(v.Field(i).Type()) 做兼容性预检如果字段本身是结构体或指针,需递归或解引用后再设值:
*string),先判断 v.Field(i).Kind() == reflect.Ptr,再用 v.Field(i).Set(reflect.ValueOf(&val))
nil *T 需先 Set(reflect.New(subType)))Set(),会 panic生产中建议封装一个带校验和错误反馈的批量赋值函数:
json:"user_name"),让 map key 更灵活if tag := field.Tag.Get("json"); tag != "" && tag != "-" { key = strings.Split(tag, ",")[0] }
基本上就这些。反射不是银弹,但批量初始化、配置注入、ORM
映射等场景下很实用。关键是守住可寻址、可导出、类型一致这三条线,就不容易翻车。