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字符串是通过程序获取的,那么就不需要对双引号进行 \ 转移处理
}

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