Go encoding/json包
Go标准库encoding/json实现JSON数据的编码与解码。
JSON序列化
json.Marshal
Go
import "encoding/json"
type User struct {
Name string
Age int
}
user := User{Name: "Tom", Age: 25}
// 序列化为JSON字节
data, err := json.Marshal(user)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data)) // {"Name":"Tom","Age":25}
json.MarshalIndent
Go
// 格式化输出(带缩进)
data, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(data))
// {
// "Name": "Tom",
// "Age": 25
// }
JSON反序列化
json.Unmarshal
Go
// JSON字符串反序列化
jsonStr := `{"Name":"Tom","Age":25}`
var user User
err := json.Unmarshal([]byte(jsonStr), &user)
if err != nil {
log.Fatal(err)
}
fmt.Println(user.Name, user.Age) // Tom 25
Unmarshal必须传递指针,否则无法修改原变量。
JSON标签
字段映射
Go
type User struct {
Name string `json:"name"` // 重命名字段
Age int `json:"age"` // 重命名字段
Email string `json:"email,omitempty"` // 空值忽略
Pass string `json:"-"` // 完全忽略
}
user := User{Name: "Tom", Age: 25}
data, _ := json.Marshal(user)
// {"name":"Tom","age":25}
// email和pass不会出现
标签选项表
| 标签 | 含义 | 示例 |
|---|---|---|
| json:"name" | 重命名字段 | Name→name |
| omitempty | 空值忽略 | json:"email,omitempty" |
| json:"-" | 完全忽略 | json:"-" |
| string | 数字转字符串 | json:"id,string" |
流式处理
json.Encoder
Go
// 写入JSON到文件
file, _ := os.Create("data.json")
encoder := json.NewEncoder(file)
user := User{Name: "Tom", Age: 25}
encoder.Encode(user)
// 直接写入响应
json.NewEncoder(w).Encode(user)
json.Decoder
Go
// 从文件读取JSON
file, _ := os.Open("data.json")
decoder := json.NewDecoder(file)
var user User
decoder.Decode(&user)
// 从请求体读取
var data struct {
Name string `json:"name"`
}
json.NewDecoder(r.Body).Decode(&data)
处理未知结构
map[string]interface{}
Go
// 解析未知JSON结构
jsonStr := `{"name":"Tom","age":25,"active":true}`
var result map[string]interface{}
json.Unmarshal([]byte(jsonStr), &result)
fmt.Println(result["name"]) // Tom
fmt.Println(result["age"]) // 25
接口类型
Go
// 任意JSON数据
var data interface{}
json.Unmarshal([]byte(jsonStr), &data)
// 类型断言
if m, ok := data.(map[string]interface{}); ok {
fmt.Println(m["name"])
}
JSON数组处理
数组序列化
Go
users := []User{
{Name: "Tom", Age: 25},
{Name: "Jerry", Age: 30},
}
data, _ := json.Marshal(users)
// [{"Name":"Tom","Age":25},{"Name":"Jerry","Age":30}]
数组反序列化
Go
jsonStr := `[{"name":"Tom"},{"name":"Jerry"}]`
var users []User
json.Unmarshal([]byte(jsonStr), &users)
fmt.Println(len(users)) // 2
嵌套结构处理
Go
type Address struct {
City string `json:"city"`
Street string `json:"street"`
}
type User struct {
Name string `json:"name"`
Address Address `json:"address"`
}
jsonStr := `{
"name": "Tom",
"address": {"city": "Beijing", "street": "Main St"}
}`
var user User
json.Unmarshal([]byte(jsonStr), &user)
自定义序列化
实现MarshalJSON
Go
type User struct {
Name string
Age int
}
func (u User) MarshalJSON() ([]byte, error) {
// 自定义序列化逻辑
return json.Marshal(map[string]interface{}{
"name": u.Name,
"age": u.Age,
"full": u.Name + " (" + strconv.Itoa(u.Age) + ")",
})
}
实现UnmarshalJSON
Go
func (u *User) UnmarshalJSON(data []byte) error {
var aux struct {
Name string
Age int
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
u.Name = aux.Name
u.Age = aux.Age
return nil
}
RawMessage延迟解析
Go
// 原始JSON保留
type Request struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"` // 不立即解析
}
// 后续按Type选择性解析Data
if req.Type == "user" {
var user User
json.Unmarshal(req.Data, &user)
}
编解码函数表
| 函数 | 用途 | 参数 |
|---|---|---|
| Marshal | 序列化 | 对象 → []byte |
| MarshalIndent | 格式化序列化 | 对象, 前缀, 缩进 |
| Unmarshal | 反序列化 | []byte, 指针 |
| NewEncoder | 创建编码器 | io.Writer |
| NewDecoder | 创建解码器 | io.Reader |
要点总结
- json.Marshal序列化结构体为JSON字节
- json.Unmarshal反序列化JSON到结构体
- Unmarshal必须传指针参数
- json标签控制字段映射和选项
- omitempty忽略空值,"-"完全忽略
- Encoder/Decoder支持流式处理
- map[string]interface{}处理未知结构
- 自定义MarshalJSON/UnmarshalJSON
- RawMessage延迟解析JSON片段
📝 发现内容有误?点击此处直接编辑