Go语言反射获取结构体字段_Golang struct反射示例
技术百科
P粉602998670
发布时间:2026-01-27
浏览: 次 要获取结构体字段名、类型、值,须先用 reflect.TypeOf 获取类型信息,再用 reflect.ValueOf 获取值信息;遍历字段需基于 Value 的 NumField/Field 方法,且传入值必须为导出结构体(非指针或先 Elem 解引用),字段需导出才能访问值与 tag,修改值前须确保 Value 可寻址且可设置,反射性能低,不宜用于热路径。
用 reflect.TypeOf 和 reflect.ValueOf 获取结构体字段信息
Go 反射要拿到结构体字段名、类型、值,必须先用 reflect.TypeOf 拿类型信息,再用 reflect.ValueOf 拿值信息。两者不能混用:前者返回 reflect.Type,后者返回 reflect.Value,字段遍历必须基于 Value 的 NumField/Field 方法。
常见错误是直接对指针类型调 NumField,结果 panic:panic: reflect: NumField of non-struct type —— 因为 *T 是指针类型,不是 struct 类型。
- 确保传入的是结构体值(非指针),或先用
.Elem()解引用 - 字段必须是导出的(首字母大写),否则
Field返回零值且不可设 -
reflect.TypeOf(x).Name()对匿名结构体返回空字符串,需用.String()看完整类型描述
遍历字段时正确处理导出性与标签(tag)
反射无法访问未导出字段(小写开头),这是 Go 的语言限制,不是反射 API 的 bug。想读取 tag(如 json:"name"),要用 StructField.Tag.Get("json"),但前提是该字段已导出。
注意 Tag 是字符串,解析靠自己;标准库用 r 提供 
Get 方法,但不自动处理 quote 或空格——比如 `json:"user_name,omitempty"` 中的 omitempty 需手动切分。
- 用
field.Type.Kind() == reflect.Struct判断是否嵌套结构体,再递归处理 - 标签值里带空格或逗号时,
Tag.Get("json")返回完整字符串,别直接当布尔用 - 如果结构体字段是接口类型(
interface{}),field.Type是interface{},但field.Interface()才是真实值
修改字段值必须传地址且字段可寻址
用反射改结构体字段值,reflect.Value 必须是可寻址的(CanAddr() == true),通常意味着原始变量得是指针,且字段本身导出。否则调 SetXxx 会 panic:reflect: reflect.Value.SetString using unaddressable value。
典型错误写法:
type User struct { Name string }
u := User{"Alice"}
v := reflect.ValueOf(u).FieldByName("Name")
v.SetString("Bob") // panic!
正确做法:
u := &User{"Alice"}
v := reflect.ValueOf(u).Elem().FieldByName("Name")
if v.CanSet() {
v.SetString("Bob")
}
-
reflect.ValueOf(u).Elem()是关键:先取指针指向的值,才能寻址 - 永远在
SetXxx前检查CanSet(),它比CanAddr()更严格(还要求字段导出) - 对 int/float 等基本类型,用
SetInt/SetFloat64,别用Set传 interface{}
性能和适用边界:别在热路径用反射遍历结构体
反射比直接字段访问慢 10–100 倍,且编译器无法内联或优化。日常序列化(如 JSON)、ORM 映射、配置绑定等场景合理,但高频循环里逐字段反射读写就是反模式。
容易被忽略的一点:反射无法获取字段定义顺序以外的信息,比如 struct 字面量里的注释、默认值、是否必填——这些只能靠额外标记(如自定义 tag)或代码生成补足。
如果项目中大量出现 reflect.Value.FieldByName,建议评估是否该用 code generation(如 stringer 或自定义 go:generate 工具)预生成类型安全的访问函数。
# go语言
# 工具
# js
# json
# go
# golang
# 循环
# 递归
# String
# int
# 标准库
# 指针
# 字符串
# 接口
# Interface
# 结构体
# Struct
# 指针类型
# Float
# using
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Windows10怎么用“讲述人”读屏辅助 Win
- c++如何实现多态性_c++ 虚函数表原理与动态绑
- 如何在Golang中解压文件_Golang com
- Go语言中slice追加操作的底层共享机制详解
- Windows10如何重置此电脑_Windows1
- Win11怎么关闭通知中心_Windows11系统
- Win11怎么设置任务栏透明_Windows11使
- c++获取当前时间戳_c++ time函数使用详解
- Win11怎么压缩文件 Win11自带压缩解压功能
- Win11 C盘满了怎么清理 Win11磁盘清理和
- 如何在JavaScript中动态拼接PHP的bas
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- 如何在包含多值的列中精准搜索指定演员?
- php485返回空数组怎么回事_php485数据接
- c++怎么编写动态链接库dll_c++ __dec
- Win11怎么设置默认输入法 Win11固定中文输
- 如何使用Golang模拟请求超时_Golang c
- Python技术债务管理_长期维护解析【教程】
- Win11怎么恢复旧版开始菜单_通过软件还原Win
- XAMPP 启动失败(Apache 突然停止)的终
- PHP接收参数值为空怎么办_判断和处理空参数方法说
- c++ stringstream用法详解_c++字
- MAC怎么解压RAR格式文件_MAC第三方解压工具
- Win11怎么设置开机自动连接宽带_Windows
- Win11怎么设置右键刷新选项_Windows11
- 如何在Golang中实现微服务负载均衡_Golan
- 如何使用 Selenium 正确获取篮球参考网站球
- MAC怎么设置程序窗口永远最前_MAC窗口置顶插件
- c++ std::future和std::prom
- 如何在 Django 中安全修改用户密码而不使会话
- Win11怎么设置声音输出设备_Windows11
- Win11输入法切换快捷键怎么改_Windows
- Windows电脑如何截屏?(四种快捷方法)
- Win11如何设置电源计划_Win11电源计划优化
- Win11怎么查看已连接wifi密码 Win11查
- 如何开启Windows的远程服务器管理工具(RSA
- Win11如何设置计划任务 Win11定时执行程序
- Win10系统更新错误0x80240034怎么办
- Windows10系统怎么查看IP地址_Win10
- php订单日志权限怎么设_php订单日志文件权限设
- Mac如何备份到iCloud_Mac桌面与文稿文件
- c++中如何求一个数的平方根_c++ sqrt函数
- MAC怎么一键隐藏桌面所有图标_MAC极简模式切换
- Win11怎么清理C盘OneDrive缓存_Win
- Windows11怎样开启游戏模式_Windows
- php查询数据怎么分组_groupby分组查询配合
- Python对象比较与排序_魔术方法解析【教程】
- Win11怎么连接投影仪_Win11多显示器投屏设
- php与c语言在嵌入式中有何区别_对比两者在硬件控
- Win11怎么清理C盘下载文件夹_Win11清理下

QQ客服