Go语言encoding/json包通过导出字段和json标签实现JSON编解码:导出字段(首字母大写)才能被处理,json:"name"自定义键名,omitempty忽略零值,"-"忽略字段,",string"字符串化编解码;需传指针给Unmarshal并检查错误,Marshal支持格式化输出;嵌套结构、切片、map及map[string]interface{}均自动递归处理。

Go 语言的 encoding/json 包提供了简洁、高效的方式处理 JSON 序列化(struct → JSON)和反序列化(JSON → struct)。关键在于结构体字段的可见性(首字母大写)、标签(json:"field_name")控制映射关系,以及正确处理嵌套、空值和类型兼容性。
结构体定义与 JSON 标签
只有导出字段(首字母大写)才能被 JSON 包读写。使用 json 标签可自定义字段名、忽略字段或控制空值行为:
-
json:"name":指定 JSON 中对应的键名 -
json:"name,omitempty":该字段为空值(零值)时不输出到 JSON -
json:"-":完全忽略该字段 -
json:",string":将数字/布尔等类型以字符串形式编解码(如"123"→int)
示例:
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email,omitempty"`
Active bool `json:"active,string"` // 接收 "true"/"false" 字符串
Secret string `json:"-"`
}反序列化:JSON 字符串 → 结构体
用 json.Unmarshal 将字节切片([]byte)解析为结构体指针。务必传入指针,否则无效果;并检查错误:
立即学习“go语言免费学习笔记(深入)”;
data := []byte(`{"id": 1, "name": "Alice", "active": "true"}`)
var u User
err := json.Unmarshal(data, &u)
if err != nil {
log.Fatal(err)
}
// u.ID == 1, u.Name == "Alice", u.Active == true注意:
- JSON 键名不区分大小写,但需与标签完全匹配(除非手动处理)
- 如果 JSON 中有额外字段而结构体没有对应字段,默认忽略
- 类型不匹配(如字符串赋给 int)会返回错误
序列化:结构体 → JSON 字符串
用 json.Marshal 将结构体转为 []byte。推荐用 json.MarshalIndent 生成格式化 JSON(便于调试):
u := User{ID: 2, Name: "Bob", Active: true}
b, err := json.Marshal(u)
// → {"id":2,"name":"Bob","active":"true"}
b, err := json.MarshalIndent(u, "", " ")
// → {
"id": 2,
"name": "Bob",
"active": "true"
}
如果字段是 nil 指针或零值且带 omitempty,不会出现在结果中。
处理嵌套、切片与 map
结构体字段可以是其他结构体、切片或 map,encoding/json 会自动递归处理:
type Post struct {
Title string `json:"title"`
Tags []string `json:"tags"`
Author *User `json:"author,omitempty"`
}
type Blog struct {
Posts []Post json:"posts"
Meta map[string]interface{} json:"meta"
}
反序列化时,只要 JSON 数据结构匹配,就能正确填充。map[string]interface{} 可用于动态或未知结构的字段(需运行时类型断言)。










