如何在Golang中获取结构体标签信息_使用reflect读取tag值
发布时间 - 2025-12-25 00:00:00 点击率:次Go中可通过reflect包获取结构体字段标签值,调用Tag.Get("key")提取json等标签,返回空字符串表示无该标签;标签选项需手动解析,如用strings.Split拆分判断omitempty或"-"。
在 Go 中,可以通过 reflect 包读取结构体字段的标签(tag)信息,最常用的是获取 json、db、validate 等自定义标签值。
获取结构体字段的 tag 值
使用 reflect.TypeOf 获取结构体类型,再通过 Field 方法遍历字段,调用 Tag.Get("key") 提取指定键的标签值。
- 必须传入结构体指针或值的反射对象,但
reflect.TypeOf接收的是类型信息,reflect.ValueOf才能获取值信息;实际中常先用reflect.TypeOf拿字段标签,再用reflect.ValueOf取值 -
Tag.Get("json")返回空字符串表示该字段没有该 tag 或 tag 值为空;不会 panic - tag 字符串格式为
`key:"value,option"`,Get方法只返回引号内的内容(不含选项),如json:"name,omitempty"→Get("json")返回"name,omitempty"
解析 tag 中的选项(如 omitempty、-)
标准库 reflect.StructTag 提供了 Get 和 Look 方法,但要拆解选项需手动处理。常见做法是按逗号分割后判断:
up
- 用
strings.Split(tagValue, ",")分割,首项是主值(如"id"),后续为选项(如"omitempty"、"-") - 若首项为
"-",表示忽略该字段(如json:"-") - 可封装一个辅助函数,例如:
func parseJSONTag(tag string) (name string, omit bool) { ... }
完整示例:打印所有字段的 json tag 名称和是否忽略空值
以下代码演示如何遍历结构体字段并解析 json 标签:
type User struct {
ID int `json:"id"`
Name string `json:"name,omitempty"`
Email string `json:"email"`
Secret string `json:"-"`
}
func printJSONTags(v interface{}) {
t := reflect.TypeOf(v)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return
}
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
jsonTag := field.Tag.Get("json")
if jsonTag == "" || jsonTag == "-" {
continue
}
parts := strings.Split(jsonTag, ",")
name := parts[0]
omit := false
for _, opt := range parts[1:] {
if opt == "omitempty" {
omit = true
break
}
}
fmt.Printf("Field: %s → JSON name: %q, omit empty: %t\n", field.Name, name, omit)
}
}
对 User{} 调用该函数,输出类似:
Field: Name → JSON name: "name", omit empty: true
Field: Email → JSON name: "email", omit empty: false
注意事项与常见坑
- 结构体字段必须是导出的(首字母大写),否则
reflect无法访问其 tag - 不能对未导出字段调用
Field(i).Tag.Get(...),会返回空字符串且无错误提示 - tag 值中的空格不自动去除,比如
json:" name "` 会被原样返回,解析时注意strings.TrimSpace - 如果需要支持多个 tag(如同时读
json和db),只需多次调用Tag.Get("xxx")
# js
# json
# go
# golang
# ai
# 标准库
# String
# 封装
# 字符串
# 结构体
# bool
# 指针
# 对象
# typeof
# 的是
# 遍历
# 空字符串
# 多个
# 只需
# 可以通过
# 自定义
# 不含
# 再用
# 可通过
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
EditPlus中的正则表达式 实战(4)
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
Python文件操作最佳实践_稳定性说明【指导】
如何确保FTP站点访问权限与数据传输安全?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
如何在腾讯云免费申请建站?
如何在宝塔面板创建新站点?
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Java遍历集合的三种方式
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
Laravel如何实现用户注册和登录?(Auth脚手架指南)
用yum安装MySQLdb模块的步骤方法
免费视频制作网站,更新又快又好的免费电影网站?
Laravel怎么使用artisan命令缓存配置和视图
Laravel如何实现邮件验证激活账户_Laravel内置MustVerifyEmail接口配置【步骤】
焦点电影公司作品,电影焦点结局是什么?
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
JavaScript如何实现错误处理_try...catch如何捕获异常?
怎么用AI帮你设计一套个性化的手机App图标?
网页设计与网站制作内容,怎样注册网站?
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
如何快速查询网站的真实建站时间?
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
香港服务器选型指南:免备案配置与高效建站方案解析
Laravel如何使用Livewire构建动态组件?(入门代码)
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
如何用西部建站助手快速创建专业网站?
Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
如何在云指建站中生成FTP站点?
浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
如何在橙子建站中快速调整背景颜色?
详解阿里云nginx服务器多站点的配置
Thinkphp 中 distinct 的用法解析
如何快速上传自定义模板至建站之星?
*服务器网站为何频现安全漏洞?
javascript中闭包概念与用法深入理解
常州企业网站制作公司,全国继续教育网怎么登录?
JavaScript中的标签模板是什么_它如何扩展字符串功能
Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】
深圳网站制作平台,深圳市做网站好的公司有哪些?
JS实现鼠标移上去显示图片或微信二维码
西安专业网站制作公司有哪些,陕西省建行官方网站?

