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) |