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"}}}
*/
}
标签:
Go基础
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!