如何使用Golang reflect遍历结构体字段_动态处理对象属性
发布时间 - 2026-01-03 00:00:00 点击率:次Go语言reflect包仅支持反射访问导出字段(首字母大写),非导出字段被忽略;需用指针获取可设置值,结合struct tag可实现通用序列化等逻辑,但性能低需谨慎使用。
Go 语言的 reflect 包支持在运行时检查和操作任意类型的值,包括结构体字段的遍历与动态读写。关键在于正确获取结构体的 reflect.Value 和 reflect.Type,并注意导出性(首字母大写)限制。
确保字段可反射访问
只有**导出字段(public field)** 才能被 reflect 读取或修改。非导出字段(小写开头)在 Value.Field(i) 或 Type.Field(i) 中会被忽略(返回零值或 panic)。若需处理私有字段,需借助 unsafe(不推荐)或重构为导出字段。
- ✅ 正确:
Name string、Age int - ❌ 不可反射:
name string、age int
基础遍历:获取字段名与值
使用 reflect.TypeOf 获取类型信息,reflect.ValueOf 获取值信息。通过循环 NumField() 遍历每个字段,用 Field(i) 和 FieldByName(name) 访问值,用 Type.Field(i) 获取结构体字段元数据(如名称、标签)。
type User struct {
Name string `json:"name" validate:"required"`
Age int `json:"age"`
}
u := User{Name: "Alice", Age: 30}
v := reflect.ValueOf(u)
t := reflect.TypeOf(u)
for i := 0; i < v.NumField(); i++ {
field := t.Field(i)
value := v.F
ield(i)
fmt.Printf("字段:%s,类型:%s,值:%v,tag:%s\n",
field.Name,
field.Type,
value.Interface(),
field.Tag.Get("json"))
}
安全读写:检查可寻址与可设置
若需**修改字段值**,必须传入指针,并确认字段可设置(CanSet())。直接传值(如 reflect.ValueOf(u))得到的是不可寻址副本,调用 SetXxx() 会 panic。
立即学习“go语言免费学习笔记(深入)”;
- 传指针:
v := reflect.ValueOf(&u).Elem() - 检查可设置:
if v.Field(i).CanSet() { v.Field(i).SetString("new") } - 注意类型匹配:SetString 要求字段是 string 类型,否则 panic
结合 struct tag 实现通用逻辑
struct tag 是反射中常用的数据载体,比如解析 JSON、校验规则、数据库映射等。可用 field.Tag.Get("key") 提取 tag 值,再按需处理。
例如实现简易 JSON 序列化逻辑:
func ToMap(v interface{}) map[string]interface{} {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
if rv.Kind() != reflect.Struct {
return nil
}
res := make(map[string]interface{})
rt := reflect.TypeOf(v)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
for i := 0; i < rv.NumField(); i++ {
field := rt.Field(i)
value := rv.Field(i)
jsonTag := field.Tag.Get("json")
if jsonTag == "-" {
continue // 忽略该字段
}
key := strings.Split(jsonTag, ",")[0]
if key == "" {
key = field.Name
}
res[key] = value.Interface()
}
return res}
不复杂但容易忽略:反射性能较低,不宜高频调用;务必做类型和可设置性检查;tag 解析建议缓存结果避免重复反射。
# js
# json
# go
# golang
# go语言
# red
# String
# if
# 结构体
# int
# 循环
# 指针
# public
# Struct
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
详解Oracle修改字段类型方法总结
如何将凡科建站内容保存为本地文件?
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
米侠浏览器网页背景异常怎么办 米侠显示修复
javascript中对象的定义、使用以及对象和原型链操作小结
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
手机网站制作与建设方案,手机网站如何建设?
如何在自有机房高效搭建专业网站?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
Python文件操作最佳实践_稳定性说明【指导】
青岛网站建设如何选择本地服务器?
如何实现建站之星域名转发设置?
浅谈javascript alert和confirm的美化
如何在建站之星绑定自定义域名?
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
如何快速生成橙子建站落地页链接?
Laravel如何使用Vite进行前端资源打包?(配置示例)
linux top下的 minerd 木马清除方法
Laravel如何创建自定义Artisan命令?(代码示例)
使用spring连接及操作mongodb3.0实例
JavaScript Ajax实现异步通信
Internet Explorer官网直接进入 IE浏览器在线体验版网址
HTML 中动态设置元素 name 属性的正确语法详解
Firefox Developer Edition开发者版本入口
如何在阿里云虚拟服务器快速搭建网站?
专业商城网站制作公司有哪些,pi商城官网是哪个?
如何为不同团队 ID 动态生成多个“认领值班”按钮
香港服务器网站推广:SEO优化与外贸独立站搭建策略
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
如何快速生成凡客建站的专业级图册?
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
郑州企业网站制作公司,郑州招聘网站有哪些?
详解vue.js组件化开发实践
Laravel怎么上传文件_Laravel图片上传及存储配置
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
如何基于云服务器快速搭建个人网站?
Laravel如何实现事件和监听器?(Event & Listener实战)
Android中AutoCompleteTextView自动提示
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
详解CentOS6.5 安装 MySQL5.1.71的方法
Linux后台任务运行方法_nohup与&使用技巧【技巧】
做企业网站制作流程,企业网站制作基本流程有哪些?
Laravel观察者模式如何使用_Laravel Model Observer配置
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
如何在七牛云存储上搭建网站并设置自定义域名?
如何在VPS电脑上快速搭建网站?


ield(i)
fmt.Printf("字段:%s,类型:%s,值:%v,tag:%s\n",
field.Name,
field.Type,
value.Interface(),
field.Tag.Get("json"))
}