如何在Golang中获取结构体标签信息_使用reflect读取tag值

发布时间 - 2025-12-25 00:00:00    点击率:
Go中可通过reflect包获取结构体字段标签值,调用Tag.Get("key")提取json等标签,返回空字符串表示无该标签;标签选项需手动解析,如用strings.Split拆分判断omitempty或"-"。

在 Go 中,可以通过 reflect 包读取结构体字段的标签(tag)信息,最常用的是获取 jsondbvalidate 等自定义标签值。

获取结构体字段的 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 提供了 GetLookup 方法,但要拆解选项需手动处理。常见做法是按逗号分割后判断:

  • 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: ID → JSON name: "id", omit empty: false
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(如同时读 jsondb),只需多次调用 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实现鼠标移上去显示图片或微信二维码  西安专业网站制作公司有哪些,陕西省建行官方网站?