
Go 结构体字段后的反引号内字符串(如 json:"message")是结构体标签,用于为字段提供元数据;它被标准库(如 encoding/json)解析,控制序列化/反序列化行为,不可通过普通字段访问,需用反射获取。
go 结构体字段后的反引号内字符串(如 `json:"message"`)是结构体标签,用于为字段提供元数据;它被标准库(如 encoding/json)解析,控制序列化/反序列化行为,不可通过普通字段访问,需用反射获取。
在 Go 中,结构体字段后紧跟的由反引号(`)包裹的字符串称为 struct tag(结构体标签),它不是字段值的一部分,而是编译期保留、运行时可通过反射访问的元数据。常见用途是指导序列化/反序列化库(如 encoding/json、encoding/xml)如何处理该字段。
⚠️ 注意:问题中写法 "json:message" 是错误的——结构体标签必须使用反引号(而非双引号),且键值对需用英文冒号分隔、值须用双引号包裹。正确写法为:
type API struct {
Message string `json:"message"`
}
✅ 正确使用示例(JSON 序列化)
package main
import (
"encoding/json"
"fmt"
)
type API struct {
Message string `json:"message"`
Code int `json:"code,omitempty"` // omitempty 表示零值时忽略该字段
}
func main() {
data := API{Message: "success", Code: 200}
b, _ := json.Marshal(data)
fmt.Println(string(b)) // 输出: {"message":"success","code":200}
}
? 如何通过反射访问 struct tag?
虽然标签不参与运行时字段访问,但可通过 reflect 包读取:
t := reflect.TypeOf(API{})
field, _ := t.FieldByName("Message")
fmt.Println(field.Tag.Get("json")) // 输出: message
field.Tag.Get("key") 是获取指定键对应值的标准方式;若键不存在,返回空字符串。
⚠️ 注意事项
- struct tag 值中的双引号必须转义或使用原始字符串(即反引号),因此绝不能用双引号包裹整个 tag(如
"json:message"会导致语法错误或被忽略); - 多个 tag 可共存,用空格分隔:
`json:"msg" xml:"msg" validate:"required"`; - 标签内容不进行语法校验,拼写错误(如
jsom:"message")仅导致对应包忽略该字段,易引发静默 bug; -
omitempty、-(忽略字段)、string(强制字符串编码)等是encoding/json特有的选项,其他包有各自约定。
掌握 struct tag 是编写可互操作 Go API 的基础能力——它让类型定义同时承载业务逻辑与序列化契约,兼顾清晰性与灵活性。











