json序列化及反序列化
json是一種輕量級的數據交換格式,易於人爲閱讀和編寫,同時也易於機器的解析和生成,是一種key-value
的格式。
由於json語言中,一切都是對象。因此,任何的數據類型都可以通過json來表示,例如,字符串、數字、對象、數組、map、結構體等等。
1 json的序列化
json的序列化是指,將現有的key-value結構的數據類型(比如結構體、map、切片)序列化成json字符串的操作。
package main
import (
"fmt"
"encoding/json"
)
// 定義一個結構體
type Monster struct {
// 如果希望json過後字段的名稱,需要打一個tag
Name string `json:"name"` // 通過反射機制實現的
Age int `json:"age"`
Birthday string
Sal float64
Skill string
}
func testStruct() {
// 聲明結構體實例
monster := Monster{
Name: "牛魔王",
Age: 500,
Birthday: "2011-11-11",
Sal: 10000.0,
Skill: "牛頭拳",
}
// 將monster序列化
data, err := json.Marshal(&monster)
if err != nil {
fmt.Printf("序列化錯誤 = %v\n", err)
}
// 輸出序列化後的結果
fmt.Printf("monster序列化後 = %v\n", string(data)) // 由於data是bate切片,所以需要轉換成字符串
}
func testMap() {
// 定義一個map
var a map[string]interface{}
// 使用map,需要make
a = make(map[string]interface{})
a["name"] = "紅孩兒"
a["age"] = 200
a["address"] = "洪崖洞"
// 將map序列化
data, err := json.Marshal(a) // 由於a map本身就是一個指針,所以不需要加引用地址的符號 &
if err != nil {
fmt.Printf("序列化錯誤 = %v\n", err)
}
// 輸出序列化後的結果
fmt.Printf("a map序列化後 = %v\n", string(data))
}
// 對切片進行序列化
func testSlice() {
var slice []map[string]interface{}
var m1 map[string]interface{}
m1 = make(map[string]interface{})
m1["name"] = "jack"
m1["age"] = 7
m1["address"] = "天津"
slice = append(slice, m1)
var m2 map[string]interface{}
m2 = make(map[string]interface{})
m2["name"] = "merry"
m2["age"] = 30
m2["address"] = [2]string{"北京", "墨西哥"}
slice = append(slice, m2)
// 將切片序列化
data, err := json.Marshal(slice) // 由於a map本身就是一個指針,所以不需要加引用地址的符號 &
if err != nil {
fmt.Printf("序列化錯誤 = %v\n", err)
}
// 輸出序列化後的結果
fmt.Printf("slice序列化後 = %v\n", string(data))
}
// 對基本數據類型序列化
func testFloat64() {
var num1 float64 = 1233.45
data, err := json.Marshal(num1) // 由於a map本身就是一個指針,所以不需要加引用地址的符號 &
if err != nil {
fmt.Printf("序列化錯誤 = %v\n", err)
}
// 輸出序列化後的結果
fmt.Printf("num1序列化後 = %v\n", string(data))
}
func main() {
// (1)將結構體進行序列化
testStruct() // monster序列化後 = {"name":"牛魔王","age":500,"Birthday":"2011-11-11","Sal":10000,"Skill":"牛頭拳"}
// (2)將map進行序列化
testMap() // a map序列化後 = {"address":"洪崖洞","age":200,"name":"紅孩兒"}
// (3)將切片進行序列化
testSlice() // slice序列化後 = [{"address":"天津","age":7,"name":"jack"},{"address":["北京","墨西哥"],"age":30,"name":"merry"}]
// (4)對基本數據類型序列化
testFloat64() // num1序列化後 = 1233.45
// 可以去 json.cn 網站上對json序列進行解析,看是否正確
}
2 json的反序列化
json的反序列化是指將json字符串反序列化成對應的數據類型(比如結構體、map、切片)的操作。
package main
// 反序列化
import (
"fmt"
"encoding/json"
)
// 定義一個結構體
type Monster struct {
Name string
Age int
Birthday string
Sal float64
Skill string
}
// 將json字符串,反序列化成struct
func unmarshalStruct() {
// str在實際開發項目中是通過網絡傳輸獲取到,或者是讀取文件獲取到
str := "{\"name\":\"牛魔王\",\"age\":500,\"Birthday\":\"2011-11-11\",\"Sal\":10000,\"Skill\":\"牛頭拳\"}"
// 定義一個Monster實例
var monster Monster
err := json.Unmarshal([]byte(str), &monster) // 這裏需要注意,反序列化時候需要將str轉成byte數組
if err != nil {
fmt.Printf("unmarshal err = %v\n", err)
}
fmt.Printf("反序列化後 monster = %v monster.Name=%v\n", monster, monster.Name)
}
// 反序列化map
func unmarshalMap() {
str := "{\"address\":\"洪崖洞\",\"age\":200,\"name\":\"紅孩兒\"}"
// 定義一個map
var a map[string]interface{}
// 反序列化不需要make,底層會自動make
err := json.Unmarshal([]byte(str), &a)
if err != nil {
fmt.Printf("unmarshal err = %v\n", err)
}
fmt.Printf("反序列化後 a = %v\n", a)
}
// 將json字符串,反序列化成切片
func unmarshalSlice() {
str := "[{\"address\":\"天津\",\"age\":7,\"name\":\"jack\"}," +
"{\"address\":[\"北京\",\"墨西哥\"],\"age\":30,\"name\":\"merry\"}]"
// 定義一個Slice
var slice []map[string]interface{}
// 不需要make
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Printf("unmarshal err = %v\n", err)
}
fmt.Printf("反序列化後 a = %v\n", slice)
}
func main() {
// (1)反序列化mstruct結構體
unmarshalStruct() // 反序列化後 monster = {牛魔王 500 2011-11-11 10000 牛頭拳} monster.Name=牛魔王
// (2)反序列化map
unmarshalMap() // 反序列化後 a = map[address:洪崖洞 age:200 name:紅孩兒]
// (3)反序列化Slice
unmarshalSlice()
// 注意:
// 1、反序列化一個json字符串時,要確保反序列化後的數據類型和原來序列化前的數據類型一致。
// 2、如果json字符串是通過程序獲取的,那麼就不需要對雙引號進行 \ 轉移處理
}