Go-19 Golang结构体和JSON相互序列化和反序列化

package main

import (
	"encoding/json"
	"fmt"
)

// Golang结构体和Json相互转换	序列化和反序列化

type Student struct {
	ID     int
	Gender string
	name   string // 私有属性不能被json包访问。
	Sno    string
}

type Stud_t struct {
	ID     int
	Gender string
	//name string // 私有属性不能被json包访问。---此处为场景1
	Name string // 共有属性时调用。---此处为场景2
	Sno  string
}

// 结构体标签Tag
type Student2 struct {
	ID     int    `json:"id"` // 通过指定tag实现json序列化该字段时的key
	Gender string `json:"gender"`
	Name   string
	Sno    string
}

type Student3 struct {
	ID     int    `json:"id"` // 通过指定tag实现json序列化该字段时的key
	Gender string `json:"gender"`
	Name   string
	Sno    string
}

// Student5 学生
type Student5 struct {
	ID     int
	Gender string
	Name   string
}

// Class 班级
type Class struct {
	Title    string
	Students []Student5
}

type Xuesheng struct {
	ID     int
	Gender string
	Name   string
}

type Banji struct {
	Title    string
	Students []Xuesheng
}

func main() {
	// 1.关于Json数据
	/*
		1.关于Json数据
			JSON 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。RESTfull Api接口中返回的数据都是json数据。
			Json的基本格式如下:
				{
					"a":"Hello",
					"b":"World"
				}
				稍微复杂点的json:
				{
					"result": [{
						"_id": "59f6ef443ce1fb0fb02c7a43",
						"title": "笔记本电脑",
						"status": "1",
						"pic": "public\\upload\\UObZahqPYzFvx_C9CQjU8KiX.png",
						"url": "12"
					}]
				}
	*/

	// 2.结构体和JSON序列化
	/*
		2.结构体和JSON序列化
			比如我们Golang要给APP或者小程序提供Api接口数据,这个时候就需要涉及到	结构体和json之间的相互转换。
			Golang JSON序列化 是把结构体数据转化成JSON格式的字符串,
			Golang JSON的反序列化是JSON数据转化成Golang中的结构体对象。
			Golang 中的序列化和反序列化主要通过"encoding/json"包中的json.Marshal()和json.Unmarshal()方法实现。
			2.1 结构体对象转化成Json字符串
				package main
				import (
					"encoding/json"
					"fmt"
				)
				type Student struct {
					ID int
					Gender string
					name string		// 私有属性不能被json包访问。
					Sno string
				}
				func main() {
					var s1 = Student{
						ID: 1,
						Gender: "男",
						name: "李四",
						Sno: "s001",
					}
					fmt.Printf("%#v \n", s1)	// main.Student{ID:1, Gender:"男", name:"李四", Sno:"s001"}
					var s,_ = json.Marshal(s1)

					jsonStr := string(s)
					fmt.Println(jsonStr)	// {ID:1, Gender:"男", name:"李四", Sno:"s001"}
				}

	*/

	// 3.结构体标签Tag
	/*
		3.结构体标签Tag
			Tag 是结构体的元信息,可以在运行的时候通过反射的机制读取出来。Tag在结构体字段的后方定义,由一对反引号包裹起来,
			具体的格式是: `key1:"value1" key2:"value2"`
			结构体tag由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。同一个结构体字段可以设置多个键值对tag,
			不同的键值对之间使用空格分隔。

		注意事项:
			为结构体编写Tag时,必须严格遵守键值对的规则。结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,
			通过反射也无法正确取值。例如不要在key和value之间添加空格。
			3.1 结构体标签Tag的序列化

			package main
			import (
				"encoding/json"
				"fmt"
			)
			type Student2 struct {
				ID int `json:"id"`	// 通过指定tag实现json序列化该字段时的key
				Gender string `json:"gender"`
				Name string
				Sno string
			}
			func main() {
				var s1 = Student2 {
					ID: 1,
					Gender: "男",
					Name: "里斯",
					Sno: "S0000123",
				}
				fmt.Printf("结构体标签 %#v \n", s1)	// 结构体标签 main.Student2{ID:1, Gender:"男", Name:"里斯", Sno:"S0000123"}
				var s,_ = json.Marshal(s1)
				jsonStr := string(s)
				fmt.Println(jsonStr)	// {"id":1,"gender":"男","Name":"里斯","Sno":"S0000123"}

			}

			3.2 结构体标签Tag的反序列化

			package main
			import (
				"encoding/json"
				"fmt"
			)
			type Student3 struct {
				ID int `json:"id"`	// 通过指定tag实现json序列化该字段时的key
				Gender string `json:"gender"`
				Name string
				Sno string
			}
			func main() {
				var s3 Student3
				var str = `{"id":1,"gender":"男","Name":"李武","Sno":"S0808008"}`
				err := json.Unmarshal([]byte(str), &s3)
				if err != nil {
					fmt.Println(err)
				}
				fmt.Printf("反序列化后的结果 %#v \n", s3)
				// 反序列化后的结果 main.Student3{ID:1, Gender:"男", Name:"李武", Sno:"S0808008"}
			}
	*/

	//4.嵌套结构体和JSON序列化反序列化
	/*
		1. 序列化
			package main
			import (
				"encoding/json"
				"fmt"
			)

			// Student 学生
			type Student5 struct {
				ID int
				Gender string
				Name string
			}

			// Class 班级
			type Class struct {
				Title string
				Students []Student
			}

			func main() {
				c := &Class{
					Title: "001",
					Students: make([]Student,0,200),
				}
				for i:=0; i<10; i++ {
					stu := Student5{
						Name: fmt.Sprintf("stu%02d", i),
						Gender: "男",
						ID: i,
					}
					c.Students=append(c.Students, stu)
				}
				// JSON 序列化:结构体-->json格式的字符串
				data,err := json.Marshal(c)
				if err != nil {
					fmt.Println("json marshal failed")
					return
				}
				fmt.Printf("json的结果是:%s \n", data)

					json的结果是:{"Title":"001","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":
				"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name"
				:"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{
				"ID":9,"Gender":"男","Name":"stu09"}]}

			}

		2. 反序列化

			package main
			type Xuesheng struct {
				ID     int
				Gender string
				Name   string
			}

			type Banji struct {
				Title    string
				Students []Xuesheng
			}
			func main(){
				xuesheng_strJson := `{"Title":"001","Students":[{"ID":0,"Gender":" 男 ","Name":"stu00"},
				{"ID":1,"Gender":" 男 ","Name":"stu01"},{"ID":2,"Gender":" 男 ","Name":"stu02"},
				{"ID":3,"Gender":" 男","Name":"stu03"},{"ID":4,"Gender":" 男 ","Name":"stu04"},{"ID":5,"Gender":" 男","Name":"stu05"},
				{"ID":6,"Gender":" 男 ","Name":"stu06"},{"ID":7,"Gender":" 男","Name":"stu07"},{"ID":8,"Gender":" 男 ","Name":"stu08"},
				{"ID":9,"Gender":" 男","Name":"stu09"}]}`

				cla := &Banji{}
				erro := json.Unmarshal([]byte(xuesheng_strJson), cla)
				if erro != nil {
					fmt.Println("json unmarshal failed!") // 这个会被执行,结合视频看一下原因
					return
				}
				fmt.Printf("结构体的结果是:%#v\n", cla)

					结构体的结果是:&main.Banji{Title:"001", Students:[]main.Xuesheng{main.Xuesheng{ID:0, Gender:" 男 ", Name:"stu00"}, main.Xuesheng{ID:1, Gender:" 男 ", Name:"stu01"}, main.Xueshen
				g{ID:2, Gender:" 男 ", Name:"stu02"}, main.Xuesheng{ID:3, Gender:" 男", Name:"stu03"}, main.Xuesheng{ID:4, Gender:" 男 ", Name:"stu04"}, main.Xuesheng{ID:5, Gender:" 男", Name:"s
				tu05"}, main.Xuesheng{ID:6, Gender:" 男 ", Name:"stu06"}, main.Xuesheng{ID:7, Gender:" 男", Name:"stu07"}, main.Xuesheng{ID:8, Gender:" 男 ", Name:"stu08"}, main.Xuesheng{ID:9, G
				ender:" 男", Name:"stu09"}}}
			}


	*/

	//5.关于Map、切片的序列化反序列化
	/*


	 */

	// 结构体序列化成json数据:
	var s1 = Student{
		ID:     1,
		Gender: "男",
		name:   "李四",
		Sno:    "s001",
	}
	fmt.Printf("%#v \n", s1) // main.Student{ID:1, Gender:"男", name:"李四", Sno:"s001"}
	var s, _ = json.Marshal(s1)

	jsonStr := string(s) // 用string来做一下格式转换
	fmt.Println(jsonStr) // {ID:1, Gender:"男", name:"李四", Sno:"s001"}

	// Json字符串转换成结构体对象:
	println()
	var jsonStr2 = `{"ID":1,"Gender":"男","name":"李四","Sno":"s00023"}` // 注意花括号里面最后一个值后面不能有符号
	// 定义一个Monster实例
	var students Stud_t
	err := json.Unmarshal([]byte(jsonStr2), &students)
	if err != nil {
		fmt.Printf("unmarshal  err=%v \n", err)
	}
	// 场景1,私有属性时运行的结果:
	//fmt.Printf("反序列化后 students=%#v  students.Name=%v  \n", students, students.name)
	// 结果是:反序列化后 students=main.Stud_t{ID:1, Gender:"男", name:"", Sno:"s00023"}  students.Name=

	// 场景2,共有属性时运行的结果:
	fmt.Printf("反序列化后 students=%#v  students.Name=%v  \n", students, students.Name)
	// 结果是:反序列化后 students=main.Stud_t{ID:1, Gender:"男", Name:"李四", Sno:"s00023"}  students.Name=李四

	// 结构体标签Tag---序列化
	println()
	var st1 = Student2{
		ID:     1,
		Gender: "男",
		Name:   "里斯",
		Sno:    "S0000123",
	}
	fmt.Printf("结构体标签 %#v \n", st1) // 结构体标签 main.Student2{ID:1, Gender:"男", Name:"里斯", Sno:"S0000123"}
	var st, _ = json.Marshal(st1)
	jsSt := string(st)
	fmt.Println(jsSt) // {"id":1,"gender":"男","Name":"里斯","Sno":"S0000123"}

	// 结构体标签Tag---反序列化
	println()
	var s3 Student3
	var str = `{"id":1,"gender":"男","Name":"李武","Sno":"S0808008"}`
	err = json.Unmarshal([]byte(str), &s3)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("反序列化后的结果 %#v \n", s3)
	// 反序列化后的结果 main.Student3{ID:1, Gender:"男", Name:"李武", Sno:"S0808008"}

	// 嵌套结构体和JSON序列化和反序列化
	println()
	c := &Class{
		Title:    "001",
		Students: make([]Student5, 0, 200),
	}
	for i := 0; i < 10; i++ {
		stud := Student5{
			Name:   fmt.Sprintf("stu%02d", i),
			Gender: "男",
			ID:     i,
		}
		c.Students = append(c.Students, stud)
	}

	// JSON 序列化:结构体-->json格式的字符串
	data, err := json.Marshal(c)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Printf("json的结果是:%s \n", data)
	/*
			json的结果是:{"Title":"001","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":
		"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name"
		:"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{
		"ID":9,"Gender":"男","Name":"stu09"}]}
	*/

	// JSON 反序列化:json格式的字符串--->结构体
	println()
	xuesheng_strJson := `{"Title":"001","Students":[{"ID":0,"Gender":" 男 ","Name":"stu00"},
{"ID":1,"Gender":" 男 ","Name":"stu01"},{"ID":2,"Gender":" 男 ","Name":"stu02"},
{"ID":3,"Gender":" 男","Name":"stu03"},{"ID":4,"Gender":" 男 ","Name":"stu04"},{"ID":5,"Gender":" 男","Name":"stu05"},
{"ID":6,"Gender":" 男 ","Name":"stu06"},{"ID":7,"Gender":" 男","Name":"stu07"},{"ID":8,"Gender":" 男 ","Name":"stu08"},
{"ID":9,"Gender":" 男","Name":"stu09"}]}`
	cla := &Banji{}
	erro := json.Unmarshal([]byte(xuesheng_strJson), cla)
	if erro != nil {
		fmt.Println("json unmarshal failed!") // 这个会被执行,结合视频看一下原因
		return
	}
	fmt.Printf("结构体的结果是:%#v\n", cla)
	/*
			结构体的结果是:&main.Banji{Title:"001", Students:[]main.Xuesheng{main.Xuesheng{ID:0, Gender:" 男 ", Name:"stu00"}, main.Xuesheng{ID:1, Gender:" 男 ", Name:"stu01"}, main.Xueshen
		g{ID:2, Gender:" 男 ", Name:"stu02"}, main.Xuesheng{ID:3, Gender:" 男", Name:"stu03"}, main.Xuesheng{ID:4, Gender:" 男 ", Name:"stu04"}, main.Xuesheng{ID:5, Gender:" 男", Name:"s
		tu05"}, main.Xuesheng{ID:6, Gender:" 男 ", Name:"stu06"}, main.Xuesheng{ID:7, Gender:" 男", Name:"stu07"}, main.Xuesheng{ID:8, Gender:" 男 ", Name:"stu08"}, main.Xuesheng{ID:9, G
		ender:" 男", Name:"stu09"}}}

	*/

	/*	以上代码的全部执行结果如下:

		main.Student{ID:1, Gender:"男", name:"李四", Sno:"s001"}
		{"ID":1,"Gender":"男","Sno":"s001"}

		反序列化后 students=main.Stud_t{ID:1, Gender:"男", Name:"李四", Sno:"s00023"}  students.Name=李四

		结构体标签 main.Student2{ID:1, Gender:"男", Name:"里斯", Sno:"S0000123"}
		{"id":1,"gender":"男","Name":"里斯","Sno":"S0000123"}

		PS C:\Users\Zhaoshan.lu\go\DaDi>
		PS C:\Users\Zhaoshan.lu\go\DaDi>
		PS C:\Users\Zhaoshan.lu\go\DaDi>
		{"ID":1,"Gender":"男","Sno":"s001"}

		反序列化后 students=main.Stud_t{ID:1, Gender:"男", Name:"李四", Sno:"s00023"}  students.Name=李四

		结构体标签 main.Student2{ID:1, Gender:"男", Name:"里斯", Sno:"S0000123"}
		{"id":1,"gender":"男","Name":"里斯","Sno":"S0000123"}

		反序列化后的结果 main.Student3{ID:1, Gender:"男", Name:"李武", Sno:"S0808008"}

		json的结果是:{"Title":"001","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},{"ID":3,"Gender":"男","N
		ame":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name":"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gen
		der":"男","Name":"stu08"},{"ID":9,"Gender":"男","Name":"stu09"}]}

		结构体的结果是:&main.Banji{Title:"001", Students:[]main.Xuesheng{main.Xuesheng{ID:0, Gender:" 男 ", Name:"stu00"}, main.Xuesheng{ID:1, Gender:" 男 ", Name:"stu01"}, main.Xueshen
		g{ID:2, Gender:" 男 ", Name:"stu02"}, main.Xuesheng{ID:3, Gender:" 男", Name:"stu03"}, main.Xuesheng{ID:4, Gender:" 男 ", Name:"stu04"}, main.Xuesheng{ID:5, Gender:" 男", Name:"s
		tu05"}, main.Xuesheng{ID:6, Gender:" 男 ", Name:"stu06"}, main.Xuesheng{ID:7, Gender:" 男", Name:"stu07"}, main.Xuesheng{ID:8, Gender:" 男 ", Name:"stu08"}, main.Xuesheng{ID:9, G
		ender:" 男", Name:"stu09"}}}

	*/

}


posted @ 2022-12-23 14:59  大海一个人听  阅读(310)  评论(0编辑  收藏  举报