基本介绍
是一种轻量级的数据交换格式,易于人阅读和编写的同时也利于机器的解析和生成,目前已经成为主流的的数据格式,任何数据类型都可以用json来表示。
通常程序再网络传输时先将数据序列化成json字符串,接收方获得json字符串后再进行反序列化回复成原来的数据。
JSON键值对是用来保存数据的一种方式,键值组合中键写在前面用双引号包裹,用冒号分隔,后面紧接着值。
JSON的解析我们可以用代码来实现,也可以用在线网站JSON在线解析格式化验证 – JSON.cn
序列化与反序列化
序列化
Json序列化是指将键值对结构的数据类型序列化成json字符串,我们直接来看案例
Marshal是我们用来进行序列化的函数。
1.结构体序列化
package main
import (
"encoding/json"
"fmt"
)
type Attribute struct {
Health int
Attack int
}
type Character struct {
Name string
Attribute
}
func structSerial() {
character := Character{
Name: "流萤",
Attribute: Attribute{
Health: 100,
Attack: 100,
},
}
/*进行序列化*/
data, err := json.Marshal(&character)
if err != nil {
fmt.Println("序列化失败", err)
}
fmt.Println("序列化后", string(data))
}
func main() {
structSerial()
}

当然我们传到前端后,前端进行反序列化,这个时候前端想要key为小写的值,我们可以通过在结构体定义时添加标签来实现。
type Attribute struct {
Health int `json:"health"`
Attack int `json:"attack"`
}
type Character struct {
Name string `json:"name"`
Attribute
}

这里tag利用了反射机制来实现,具体原理我们后面再说。
2.map序列化
func mapSerial() {
var a map[string]interface{}
a = make(map[string]interface{})
a["name"] = "昔涟"
a["Health"] = "100"
data, err := json.Marshal(a)
if err != nil {
fmt.Println("序列化失败", err)
}
fmt.Println("map序列化后", string(data))
}
func main() {
structSerial()
mapSerial()
}

3.切片序列化
func sliceSerial() {
var slice []map[string]interface{}
var m1 map[string]interface{}
m1 = make(map[string]interface{})
m1["name"] = "遐蝶"
m1["Health"] = "100"
slice = append(slice, m1)
var m2 map[string]interface{}
m2 = make(map[string]interface{})
m2["name"] = "白厄"
m2["Health"] = "100"
slice = append(slice, m2)
data, err := json.Marshal(slice)
if err != nil {
fmt.Println("序列化失败", err)
}
fmt.Println("slice序列化后", string(data))
}
func main() {
structSerial()
mapSerial()
sliceSerial()
}

反序列化
为了获取一个反序列化字符串,我们把上面的函数魔改一下,然后直接来一个综合一点的案例。
package main
import (
"encoding/json"
"fmt"
)
type Attribute struct {
Health int `json:"health"`
Attack int `json:"attack"`
}
type Character struct {
Name string `json:"name"`
Attribute
}
func structSerial() string {
character := Character{
Name: "流萤",
Attribute: Attribute{
Health: 100,
Attack: 100,
},
}
//进行序列化
data, err := json.Marshal(&character)
if err != nil {
fmt.Println("序列化失败", err)
}
return string(data)
}
func mapSerial() string {
var a map[string]interface{}
a = make(map[string]interface{})
a["name"] = "昔涟"
a["Health"] = "100"
data, err := json.Marshal(a)
if err != nil {
fmt.Println("序列化失败", err)
}
return string(data)
}
func sliceSerial() string {
var slice []map[string]interface{}
var m1 map[string]interface{}
m1 = make(map[string]interface{})
m1["name"] = "遐蝶"
m1["Health"] = "100"
slice = append(slice, m1)
var m2 map[string]interface{}
m2 = make(map[string]interface{})
m2["name"] = "白厄"
m2["Health"] = "100"
slice = append(slice, m2)
data, err := json.Marshal(slice)
if err != nil {
fmt.Println("序列化失败", err)
}
return string(data)
}
func main() {
structStr := structSerial()
fmt.Println("序列化后", structStr)
mapStr := mapSerial()
fmt.Println("map序列化后", mapStr)
sliceStr := sliceSerial()
fmt.Println("slice序列化后", sliceStr)
}
我们通过将函数返回值改为字符串来获取到一个序列化之后的字符串,我们再来进行反序列化,还原出原本的数据结构。
func structUnmarshal(str string) {
var newCharacter Character
err := json.Unmarshal([]byte(str), &newCharacter)
if err != nil {
fmt.Println(err)
}
fmt.Println("反序列化后:", newCharacter)
}
func mapUnmarshal(str string) {
var newMap map[string]interface{}
err := json.Unmarshal([]byte(str), &newMap)
if err != nil {
fmt.Println(err)
}
fmt.Println("map反序列化后:", newMap)
}
func sliceUnmarshal(str string) {
var slice []map[string]interface{}
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Println(err)
}
fmt.Println("slice反序列化后", slice)
}
func main() {
structStr := structSerial()
fmt.Println("序列化后", structStr)
mapStr := mapSerial()
fmt.Println("map序列化后", mapStr)
sliceStr := sliceSerial()
fmt.Println("slice序列化后", sliceStr)
//反序列化
structUnmarshal(structStr)
mapUnmarshal(mapStr)
sliceUnmarshal(sliceStr)
}











