JSON(JavaScript Object Notation)是一种常见的数据交换格式。Go 标准库提供了
encoding/json
包,用于方便地将结构体与 JSON 之间互转。
一、序列化(Marshal)
将 Go 中的数据结构(如结构体、map、slice 等)转换为 JSON 字符串,称为“序列化”。
1. 基本示例:
package mainimport ("encoding/json""fmt"
)type Person struct {Name stringAge int
}func main() {p := Person{Name: "Tom", Age: 30}data, _ := json.Marshal(p)fmt.Println(string(data)) // 输出:{"Name":"Tom","Age":30}
}
二、反序列化(Unmarshal)
将 JSON 字符串转换为 Go 数据结构的过程,称为“反序列化”。
示例:
jsonStr := `{"Name":"Alice","Age":25}`
var p Person
json.Unmarshal([]byte(jsonStr), &p)
fmt.Println(p.Name, p.Age) // 输出:Alice 25
三、结构体字段标签(Tag)
Go 的 json
标签用于控制字段与 JSON 键之间的映射。
type Person struct {Name string `json:"name"` // 指定键为 nameAge int `json:"age"`
}
输出示例:
p := Person{Name: "Tom", Age: 20}
data, _ := json.Marshal(p)
fmt.Println(string(data)) // {"name":"Tom","age":20}
四、控制字段行为的标签
标签形式 | 含义 |
json:"name" | 重命名字段为 name |
json:"name,omitempty" | 若字段值为空则忽略 |
json:"-" | 忽略该字段,不进行序列化/反序列化 |
示例:
type User struct {Name string `json:"name"`Token string `json:"-"` // 忽略Age int `json:"age,omitempty"` // 0 则不输出
}
五、处理 map 和切片
data := map[string]interface{}{"name": "Go","year": 2009,
}
bytes, _ := json.Marshal(data)
fmt.Println(string(bytes)) // {"name":"Go","year":2009}
六、嵌套结构体序列化
type Address struct {City string `json:"city"`State string `json:"state"`
}type User struct {Name string `json:"name"`Address Address `json:"address"`
}
序列化会生成嵌套的 JSON 结构:
{"name": "Bob","address": {"city": "Beijing","state": "CN"}
}
七、反序列化未知结构(使用 map[string]interface{}
)
str := `{"name":"Go","version":1.18}`
var result map[string]interface{}
json.Unmarshal([]byte(str), &result)fmt.Println(result["name"]) // Go
fmt.Println(result["version"].(float64)) // 1.18
注意:数字默认会被解析为 float64
。
八、处理 JSON 数组
jsonStr := `[{"name":"Tom"},{"name":"Jerry"}]`var users []map[string]string
json.Unmarshal([]byte(jsonStr), &users)
fmt.Println(users[0]["name"]) // Tom
九、小结
功能 | 方法名 | 类型要求 |
序列化 | json.Marshal() | 输入:结构体/map/slice |
反序列化 | json.Unmarshal() | 输出:指针(结构体/map) |