Golang的json序列化和反序列化

json序列化及反序列化

json是一種輕量級的數據交換格式,易於人爲閱讀和編寫,同時也易於機器的解析和生成,是一種key-value的格式。
由於json語言中,一切都是對象。因此,任何的數據類型都可以通過json來表示,例如,字符串、數字、對象、數組、map、結構體等等。

json解析的網站

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字符串是通過程序獲取的,那麼就不需要對雙引號進行 \ 轉移處理
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章