Go中结构体字段加JSON标签的正确写法是在字段声明后用反引号包裹json:"key"或json:"key,option",仅限struct定义内;变量声明无需且不可加标签,且字段必须导出(首字母大写)才生效。

结构体字段加 json 标签的写法
Go 里给结构体字段加 JSON 标签,是在字段声明后紧跟反引号包裹的字符串,格式为 `json:"字段名"` 或带选项的 `json:"字段名,选项"`。标签本身不参与变量声明,而是修饰结构体定义;变量声明和普通结构体一样,用 var、:= 或字面量即可。
常见错误是把标签写在变量声明行(比如 var u User `json:"user"`),这会报语法错误——标签只能出现在 struct 字段定义中。
-
json:"name":序列化时用name作为键名 -
json:"name,omitempty":值为零值(如空字符串、0、nil)时不输出该字段 -
json:"-":完全忽略该字段(不序列化也不反序列化) -
json:"name,string":强制将数字类型(如int64)转成字符串编码(常用于时间戳或 ID)
声明变量时不需要重复写标签
结构体类型定义好后,变量声明跟有没有 JSON 标签完全无关。标签只在调用 json.Marshal 或 json.Unmarshal 时起作用。
例如:
立即学习“go语言免费学习笔记(深入)”;
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
var u User // ✅ 正确
u := User{ID: 123, Name: "Alice"} // ✅ 正确
var u2 *User = &User{ID: 456} // ✅ 正确
注意:json 标签对字段的可见性有要求——只有首字母大写的导出字段才能被 json 包访问。如果写 name string `json:"name"`(小写 name),序列化结果里永远不会有这个字段。
嵌套结构体和匿名字段的标签处理
嵌套结构体字段默认会扁平展开,除非显式命名。匿名字段会继承其内部字段的 JSON 标签(如果有的话),但也可以被外层结构体重写。
Node.js 可靠编程技能。避免事件循环阻塞、异步陷阱、ESM 兼容问题和内存泄漏。触发词:Node.js 开发、async/await、流处理、性能优化、安全编码。
例如:
立即学习“go语言免费学习笔记(深入)”;
type Base struct {
CreatedAt int64 `json:"created_at"`
}
type Post struct {
Base // 匿名字段,CreatedAt 会直接出现在 Post 的 JSON 中
Title string `json:"title"`
Content string `json:"content"`
}
此时 json.Marshal(Post{Base: Base{CreatedAt: 1712345678}, Title: "Hi"}) 输出:{"created_at":1712345678,"title":"Hi","content":""}。
如果不想继承,可加 json:"-" 到匿名字段上;如果想重命名,得用具名字段 + 自定义 MarshalJSON 方法。
容易被忽略的大小写与零值行为
最常踩的坑有两个:一是字段未导出(小写开头),导致 json.Marshal 输出空对象 {};二是用了 omitempty 却没意识到零值判断规则——""、0、false、nil 都算零值,哪怕你希望空字符串也保留,就不能加 omitempty。
另外,json 包不会自动处理指针字段的 nil 解引用,比如 *string 字段为 nil 时,加了 omitempty 就直接跳过;不加则会 panic(除非你手动处理)。这种边界情况在 API 请求体或配置解析里特别容易出问题。

















