go语言与JSON
1. 字节序复习
大端法:高存低,低存高
小端法:高存高,低存低
2. 序列化
func Marshal(v interface{}) ([]byte, error)
- 参数:待序列化的数据
- 返回值:json串
2.1 结构体序列化
-
要求 结构体类型名 和 成员(属性)名 必须大写(包作用域),才能在json包中可见。(因为json的函数是在其他包中,必须要让其他包可见要转换的结构体)
-
否则,不报错!但不做序列化转换。
{“Name”:“张三”,“Age”:29,“Score”:98.9,“Id”:1001}
// 结构体序列化
func StructSerial(v interface{}) {
jStr, err := json.Marshal(v)
if err != nil {
panic(err)
}
fmt.Println(string(jStr))
}
2.2 map序列化
-
定义map变量,不使用make初始化,不能存储数据
{“Age”:19,“Id”:9527,“Name”:“华安”,“food”:[“鸡翅膀”,“含笑半步癫”,“一日散命散”]}
// map 序列化
func MapSerial() {
var m map[string]interface{} // key是string类型, value是自定义数据类型
// 初始化空间
m = make(map[string]interface{}) // 不指定大小可以自动添加后扩容
m["Name"] = "华安"
m["Age"] = 19
m["Id"] = 9527
m["food"] = [3]string{"鸡翅膀", "含笑半步癫", "一日散命散"}
jStr, err := json.Marshal(m)
if err != nil {
panic(err)
}
fmt.Println(string(jStr))
}
2.3 slice切片序列化
- 定义一个slice变量可以不初始化, 直接使用append()向其中添加数据, slice本质是一个结构体
[
{
"Age":19,
"Id":9527,
"Name":"华安",
"food":[
"鸡翅膀",
"含笑半步癫",
"一日散命散"
]
},
{
"Age":16,
"Id":521,
"Name":"秋香",
"food":[
"鸡翅膀",
"一日散命散"
],
"教师":{
"Name":"alin",
"Age":21,
"Addr":"天津"
}
}
]
func SliceSerial() {
// 定义一个map切片
var slice []map[string]interface{}
// 初始化map数据
m1 := make(map[string]interface{})
m1["Name"] = "华安"
m1["Age"] = 19
m1["Id"] = 9527
m1["food"] = [3]string{"鸡翅膀", "含笑半步癫", "一日散命散"}
m2 := make(map[string]interface{})
m2["Name"] = "秋香"
m2["Age"] = 16
m2["Id"] = 521
m2["food"] = []string{"鸡翅膀", "一日散命散"}
m2["教师"] = Teacher{"alin", 21, "天津"}
slice = append(slice, m1)
slice = append(slice, m2)
jStr, err := json.Marshal(slice)
if err != nil {
panic(err)
}
fmt.Println(string(jStr))
}
3. 结构体标签
-
用途:在序列化时,重新制定json key值
-
语法:使用反引号包裹。key:value
- key : json、自定义key
- value:必须使用""包裹
`json:"标签,选项"`
注意:上述语法中不能有空格
标签后面的选项
-
作用是不进行序列化,omitempty
作用是忽略0和空指string
作用是序列化时类型转化为字符串,序列化后会有""
package main
import (
"encoding/json"
"fmt"
)
//type Student5 struct {
// Name string `json:"stu_name"`
// Age int `json:"stu_age"`
// Score float64
// Id int
//}
type Student5 struct {
Name string `json:"-"` // 序列化结果中没有这个属性
Age int `json:"age,omitempty"`
Score float64 `json:"score,string"`
Id int `json:"id"`
}
// 结构体序列化
func StructSerial1(v interface{}) {
jStr, err := json.Marshal(v)
if err != nil {
panic(err)
}
fmt.Println(string(jStr))
}
func main() {
stu := Student5{"张三", 0, 98.9, 1001}
StructSerial1(stu)
}
输出结果:{"score":"98.9","id":1001}
4. 反序列化
func Unmarshal(data []byte, v interface{}) error
- 参数1:序列化后产生的json串
- 参数2:用来传出反序列化后的原始数据。使用时传指针。
- 返回值:一旦err有数据,说明反序列化失败。
4.1 结构体反序列化
- 用来接收反序列化的结构体类型,不许与原序列化的结构体类型严格一致
type Student6 struct {
Name string
Age int
Score float64
Id int
}
type Student7 struct {
Name string `json:"-"` // 序列化结果中没有这个属性
Age int `json:"age,omitempty"`
Score float64 `json:"score,string"`
Id int `json:"id"`
}
func StructUnSerial() {
str := `{"Name":"张三","Age":29,"Score":98.9,"Id":1001}`
var stu Student6
err := json.Unmarshal([]byte(str), &stu)
if err != nil {
panic(err)
}
fmt.Println(stu)
}
func StructUnSerial2() {
str := `{"score":"98.9","id":1001}`
var stu Student7
err := json.Unmarshal([]byte(str), &stu)
if err != nil {
panic(err)
}
fmt.Println(stu)
}
func main() {
StructUnSerial()
StructUnSerial2()
}
{张三 29 98.9 1001}
{ 0 98.9 1001}
4.2 map反序列化
Unmarshal函数会帮助我们做map的容量make操作,用来接收的map不用自己make
- 需要传取地址的map
func MapDeSerial() {
str := `{"Age":19,"Id":9527,"Name":"华安","food":["鸡翅膀","含笑半步癫","一日散命散"]}`
var m map[string]interface{}
err := json.Unmarshal([]byte(str), &m)
if err != nil {
panic(err)
}
fmt.Println(m)
}
4.3 slice反序列
- 需要传入取地址的slice
func SliceDeSerial() {
str := `[
{
"Age":19,
"Id":9527,
"Name":"华安",
"food":[
"鸡翅膀",
"含笑半步癫",
"一日散命散"
]
},
{
"Age":16,
"Id":521,
"Name":"秋香",
"food":[
"鸡翅膀",
"一日散命散"
],
"教师":{
"Name":"alin",
"Age":21,
"Addr":"天津"
}
}
]`
var slice []map[string]interface{}
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
panic(err)
}
for _, data := range slice {
fmt.Println(data)
}
}