Go语言基础: JSON序列化
JSON 是一种轻量级的数据交换格式。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
首先得熟悉结构体:
package main import "fmt" type Student struct { ID int Gender string Name string Sno string } func main() { var s = Student{ ID: 12, Gender: "男", Name: "李四", Sno: "001", } fmt.Printf("%#v\n", s) }
如上代码中定义了一个结构体并且打印
结果: main.Student{ID:12, Gender:"男", Name:"李四", Sno:"001"}
转化为JSON字符串
package main import ( "encoding/json" "fmt" ) type Student struct { ID int Gender string Name string Sno string } func main() { var s = Student{ ID: 12, Gender: "男", Name: "李四", Sno: "001", } // fmt.Printf("%#v\n", s) jsonbByte, _ := json.Marshal(s) jsonStr := string(jsonbByte) fmt.Println(jsonStr) }
json.Marshal返回的是一个Byte类型的切片:
package json // import "encoding/json" func Marshal(v any) ([]byte, error) Marshal returns the JSON encoding of v.
然后用string将其转为字符串并打印
那么JSON字符串也可以转化为结构体
package main import ( "encoding/json" "fmt" ) type Student struct { ID int Gender string Name string Sno string } func main() { // 使用反引号就无须转义字符 var str = `{"ID":12,"Gender":"男","Name":"李四","Sno":"001"}` var s Student err := json.Unmarshal([]byte(str), &s) if err != nil { fmt.Println(err) } fmt.Printf("%#v", s) }
这里用到Unmarshal函数来转换JSON字符串
package json // import "encoding/json" func Unmarshal(data []byte, v any) error Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
代码中Unmarshal函数接收两个参数,第一个是字节类型的切片,第二个是结构体变量地址。
要注意的是,如果结构体中的某字段的首字母是小写的,那么是不能转化为JSON字符串的,因为是该字段是私有的。
可以利用结构体标签来更改JSON字符串中的key的形式
package main import ( "encoding/json" "fmt" ) type Student struct { ID int `json:"id"` // 添加了结构体标签 Gender string `json:"gender"` Name string `json:"name"` Sno string `json:"sno"` } func main() { var s = Student{ ID: 12, Gender: "男", Name: "李四", Sno: "001", } // fmt.Printf("%#v\n", s) jsonbByte, _ := json.Marshal(s) jsonStr := string(jsonbByte) fmt.Println(jsonStr) }
打印结果: {"id":12,"gender":"男","name":"李四","sno":"001"}
显然这个形式已经与之前的不一样了,首字母已经被改成了小写,这就是结构体标签作用之一。
下面是嵌套结构体的转化
package main import ( "encoding/json" "fmt" ) // Student 学生结构体 type Student struct { ID int `json:"id"` Gender string `json:"gender"` Name string `json:"name"` Sno string `json:"sno"` } // Class 班级结构体 type Class struct { Title string Students []Student } func main() { c := Class{ Title: "001 Class", Students: make([]Student, 0), // make创建切片 } for i := 1; i < 10; i++ { s := Student{ ID: i, Gender: "男", Name: fmt.Sprintf("stu_%v", i), } c.Students = append(c.Students, s) // 加入切片 } fmt.Println(c) strByte, err := json.Marshal(c) if err != nil { fmt.Println(err) } else { strJson := string(strByte) fmt.Println(strJson) } }
打印结果
{001 Class [{1 男 stu_1 } {2 男 stu_2 } {3 男 stu_3 } {4 男 stu_4 } {5 男 stu_5 } {6 男 stu_6 } {7 男 stu_7 } {8 男 stu_8 } {9 男 stu_9 }]} {"Title":"001 Class","Students":[{"id":1,"gender":"男","name":"stu_1","sno":""},{"id":2,"gender":"男","name":"stu_2","sno":""},{"id":3,"gender":"男","name":"stu_3","sno":""},{"id":4,"gender":"男","name":_4","sno":""},{"id":5,"gender":"男","name":"stu_5","sno":""},{"id":6,"gender":"男","name":"stu_6","sno":""},{"id":7,"gender":"男","name":"stu_7","sno":""},{"id":8,"gender":"男","name":"stu_8","sno":""},{:9,"gender":"男","name":"stu_9","sno":""}]}
第一行是结构体信息,其后才是JSON数据
在这个JSON中是数据嵌套存放的,看着比较乱,可以借助 JSON在线解析 解析该数据
解析结果:
{ "Title":"001 Class", "Students":[ { "id":1, "gender":"男", "name":"stu_1", "sno":"" }, { "id":2, "gender":"男", "name":"stu_2", "sno":"" }, { "id":3, "gender":"男", "name":"stu_3", "sno":"" }, { "id":4, "gender":"男", "name":"stu_4", "sno":"" }, { "id":5, "gender":"男", "name":"stu_5", "sno":"" }, { "id":6, "gender":"男", "name":"stu_6", "sno":"" }, { "id":7, "gender":"男", "name":"stu_7", "sno":"" }, { "id":8, "gender":"男", "name":"stu_8", "sno":"" }, { "id":9, "gender":"男", "name":"stu_9", "sno":"" } ] }
那么又如何将这个字符串再转化回去?
如下所示
package main import ( "encoding/json" "fmt" ) // Student 学生结构体 type Student struct { ID int `json:"id"` Gender string `json:"gender"` Name string `json:"name"` Sno string `json:"sno"` } // Class 班级结构体 type Class struct { Title string Students []Student } func main() { str := `{"Title":"001 Class","Students":[{"id":1,"gender":"男","name":"stu_1","sno":""},{"id":2,"gender":"男","name":"stu_2","sno":""},{"id":3,"gender":"男","name":"stu_3","sno":""},{"id":4,"gender":"男","name":"stu_4","sno":""},{"id":5,"gender":"男","name":"stu_5","sno":""},{"id":6,"gender":"男","name":"stu_6","sno":""},{"id":7,"gender":"男","name":"stu_7","sno":""},{"id":8,"gender":"男","name":"stu_8","sno":""},{"id":9,"gender":"男","name":"stu_9","sno":""}]}` var c = &Class{} // 地址 err := json.Unmarshal([]byte(str), c) if err != nil { fmt.Println(err) } fmt.Printf("%#v", *c) }
打印结果
main.Class{Title:"001 Class", Students:[]main.Student{main.Student{ID:1, Gender:"男", Name:"stu_1", Sno:""}, main.Student{ID:2, Gender:"男", Name:"stu_2", Sno:""}, main.Student{ID:3, Gender:"男", Name:"stu_3", Sno:""}, main.Student{ID:4, Gender:"男", Name:"stu_4", Sno:""}, main.Student{ID:5, Gender:"男", Name:"stu_5", Sno:""}, main.Student{ID:6, Gender:"男", Name:"stu_6", Sno:""}, main.Student{ID:7, Gender:"男", Name:"stu_7", Sno:""}, main.Student{ID:8, Gender:"男", Name:"stu_8", Sno:""}, main.Student{ID:9, Gender:"男", Name:"stu_9", Sno:""}}}
JSON序列化就是将结构体转化为JSON字符串
JSON反序列化就是将JSON字符串转化为结构体
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具