Go中可通过reflect包获取结构体字段标签值,调用Tag.Get("key")提取json等标签,返回空字符串表示无该标签;标签选项需手动解析,如用strings.Split拆分判断omitempty或"-"。
在 Go 中,可以通过 reflect 包读取结构体字段的标签(tag)信息,最常用的是获取 json、db、validate 等自定义标签值。
使用 reflect.TypeOf 获取结构体类型,再通过 Field 方法遍历字段,调用 Tag.Get("key") 提取指定键的标签值。
reflect.TypeOf 接收的是类型信息,reflect.ValueOf 才能获取值信息;实际中常先用 reflect.TypeOf 拿字段标签,再用 reflect.ValueOf 取值Tag.Get("json") 返回空字符串表示该字段没有该 tag 或 tag 值为空;不会 panic`key:"value,option"`,Get 方法只返回引号内的内容(不含选项),如 json:"name,omitempty" → Get("json") 返回 "name,omitempty"
标准库 reflect.StructTag 提供了 Get 和 Lookup 方法,但要拆解选项需手动处理。常见做法是按逗号分割后判断:
strings.Split(tagValue, ",") 分割,首项是主值(如 "id"),后续为选项(如 "omitempty"、"-"
)"-",表示忽略该字段(如 json:"-")func parseJSONTag(tag string) (name string, omit bool) { ... }
以下代码演示如何遍历结构体字段并解析 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{} 调用该函数,输出类似:
reflect 无法访问其 tagField(i).Tag.Get(...),会返回空字符串且无错误提示json:" name "` 会被原样返回,解析时注意 strings.TrimSpace
json 和 db),只需多次调用 Tag.Get("xxx")