Go语言reflect包操作结构体字段需注意:仅导出字段可读写;读取用Field(i)/FieldByName并注意值或指针类型;写入需可寻址且可设置,通常传指针并调用Elem();遍历字段需检查CanInterface/CanSet;标签通过StructField.Tag.Get读取。

Go语言的reflect包允许在运行时动态获取和操作结构体字段,但需注意:只有**导出字段(首字母大写)才能被反射读取或修改**;非导出字段只能读取类型信息,无法访问值。
获取结构体字段值(读取)
使用reflect.ValueOf().Field(i)或reflect.ValueOf().FieldByName("Name")获取字段值。必须确保传入的是结构体值(而非指针)或已解引用的指针值。
- 若原始变量是结构体实例(如
u := User{...}),直接reflect.ValueOf(u).FieldByName("Name") - 若原始变量是指针(如
u := &User{...}),需先调用.Elem()获取底层值:reflect.ValueOf(u).Elem().FieldByName("Name") - 调用
.Interface()将reflect.Value转为实际类型,再做类型断言(如v.Interface().(string))
修改结构体字段值(写入)
修改字段前必须满足两个条件:字段可寻址(addressable)且可设置(settable)。通常需传入结构体指针,并通过.Elem()进入可修改的值对象。
- 错误示例:
reflect.ValueOf(u).FieldByName("Age").SetInt(25)—— 若u是值类型,返回的Value不可寻址,会panic - 正确做法:
reflect.ValueOf(&u).Elem().FieldByName("Age").SetInt(25) - 修改字符串字段:
.FieldByName("Name").SetString("Alice") - 修改任意类型字段:先用
.Interface()获取原值,构造新值后用.Set(reflect.ValueOf(newValue))
安全地遍历和操作所有导出字段
结合reflect.Type和reflect.Value,可统一处理结构体所有可访问字段:
易学易用:友好的系统操作界面,无须具备专业知识,即可熟练的使用系统。功能完善:具备新建、修改、明细、审批、导入、导出、删除、批量、打印等功能。模型开发:自定义表单字段选项零代码二次开发,可无限扩展后台功能模块。 维护方便:基于互联网技术B/S体系结构,实施快速,极大的减少系统升级维护工作。售后保证:专业的技术研发团队,可提供可靠的产品迭代、版本升级和技术支持服务。超低成本:一次投入终身使用、用户不
立即学习“go语言免费学习笔记(深入)”;
- 用
t := reflect.TypeOf(v)和v := reflect.ValueOf(v)分别获取类型与值信息 - 循环
t.NumField(),用t.Field(i)获取字段元信息(名称、标签等),用v.Field(i)获取对应值 - 检查
v.Field(i).CanInterface()和v.Field(i).CanSet()避免非法操作 - 常用场景:通用JSON/DB映射、日志打印、默认值填充
注意字段标签(struct tag)的读取
字段标签(如`json:"name"`)属于类型信息,需通过reflect.StructField.Tag访问:
-
field, ok := t.FieldByName("Name")→if ok { tag := field.Tag.Get("json") } -
tag.Get("xxx")安全获取指定键的值,未定义则返回空字符串 - 标签内容不参与反射值操作,仅用于元数据描述









