Go语言JSON 序列化与反序列化 -《Go语言实战指南》

225 阅读2分钟

JSON(JavaScript Object Notation)是一种常见的数据交换格式。Go 标准库提供了 encoding/json 包,用于方便地将结构体与 JSON 之间互转。


一、序列化(Marshal)

将 Go 中的数据结构(如结构体、map、slice 等)转换为 JSON 字符串,称为“序列化”。

1. 基本示例:

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string
    Age  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.Namep.Age) // 输出:Alice 25

三、结构体字段标签(Tag)

Go 的 json 标签用于控制字段与 JSON 键之间的映射。

type Person struct {
    Name string `json:"name"`  // 指定键为 name
    Age  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)