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 和 Lookup 方法,但要拆解选项需手动处理。常见做法是按逗号分割后判断:
- 用
strings.Split(tagValue, ",")分割,首项是主值(如"id"),后续为选项(如"omitempty"、"-") - 若首项为
"-",表示忽略该字段(如json:"-") - 可封装一个辅助函数,例如:
func parseJSONTag(tag string) (name string, omit bool) { ... }
完整示例:打印所有字段的 json tag 名称和是否忽略空值
以下代码演示如何遍历结构体字段并解析 json 标签:
立即学习“go语言免费学习笔记(深入)”;
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")










