go结构体字段加json:"name"标签可自定义json键名,须用反引号包裹、逗号分隔;常见错误是引号不闭合或漏逗号;支持-忽略字段、omitempty省略零值、string强制转字符串等修饰符。

结构体字段加 json 标签就能改字段名,但别漏掉逗号
直接在字段后面写 json:"xxx" 就能控制序列化后的键名。最常见错误是写成 json:"xxx" `json:"yyy"` 这种双引号没闭合、或忘记逗号导致编译失败。
比如:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
ID int64 `json:"id,string"` // 转成字符串输出
}
注意:标签里必须用反引号包裹,且每个字段的 struct tag 是独立的——不能省略逗号,也不能混用单引号。
json: 标签里的特殊符号会影响序列化行为
除了重命名,json 标签还支持几个关键修饰符,它们会改变字段是否参与序列化、怎么序列化:
-
json:"-":完全忽略该字段(不输出,也不从 JSON 解析) -
json:"name,omitempty":值为零值(""、0、false、nil)时跳过该字段 -
json:"name,string":强制把数字类型(如int、bool)转成字符串输出(API 兼容老系统常用) -
json:"name,omitempty,string":两个修饰符可以共存,顺序无关
特别注意:omitempty 对指针或接口类型的零值判断较复杂,比如 *string 指向 nil 会被跳过,但指向空字符串 "" 不会跳过。
嵌套结构体字段名冲突时,标签优先级高于字段名
如果嵌套结构体里有同名字段(比如都叫 ID),又都想导出为不同 JSON 键,就得靠标签区分。Go 不会自动加前缀,全靠你手动指定:
type Order struct {
ID int64 `json:"order_id"`
User User `json:"user"`
UserID int64 `json:"user_id"` // 即使 User 里也有 ID,这里仍可单独定义
}
type User struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
此时序列化 Order 得到的是 {"order_id":123,"user":{"id":456,"name":"Alice"},"user_id":456}。没有标签时,User.ID 默认变成 "ID"(首字母大写),加了标签才可控。
用 json.RawMessage 跳过结构体解析,避免字段名硬编码失效
当 API 返回的 JSON 字段名动态变化(比如带版本前缀 v1_data / v2_payload),或者你想延迟解析某块数据,硬写 json:"xxx" 就会失效。这时用 json.RawMessage 把原始字节存下来,后续再按需解析:
type Response struct {
Code int `json:"code"`
Data json.RawMessage `json:"data"` // 不做结构化解析
}
// 后续:
var payload map[string]interface{}
json.Unmarshal(response.Data, &payload)
这种写法绕过了字段名绑定,也避免了因服务端改名导致的解码失败。但代价是失去编译期字段检查和 IDE 自动补全——适合过渡期或高度动态场景。
实际项目里,字段名一旦上线就尽量别频繁改;但如果真要兼容多版本,光靠标签不够,得配合 json.RawMessage 或自定义 UnmarshalJSON 方法。标签只是第一道控制,不是万能胶。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










