9.3 Go json

9.3 Go json

json是一种轻量级的数据交换格式,易于机器解析,是种key-value格式。

JavaScript Object Notation是中种主流的数据格式。

json常用于网络传输

先将程序数据(如map、struct等)序列化成json字符串
接收方得到json字符串时,进行反序列化成原有数据类型

JS语言中,任何数据类型都可以通过JSON表示,如字符串、数字、对象、数组、map、结构体等。
JSON用键值对保存数据

1.1. 在线解析json网址

https://www.json.cn/

1.2. json序列化

序列化是指将key-value结构的数据类型如struct、map、切片序列化成json字符串。

实例

package main

import (
    "encoding/json"
    "fmt"
)

//自定制序列化后,json字符串的key名,可以用struct的tag标签
type Student struct {
    Name  string  `json:"姓名"`
    Age   int     `json:"年纪"`
    Score float64 `json:"成绩"`
}

//序列化结构体
func testStruct() {
    stu := Student{
        "老王",
        19,
        99.9,
    }
    //序列化结构体
    data, err := json.Marshal(&stu)
    if err != nil {
        fmt.Printf("序列化出错,", err)
    }
    //data是数组切片,需要类型强转
    fmt.Printf("序列化结果:%v\n", string(data))
}

//序列化map
func testMap() {
    mymap := make(map[string]string)
    mymap["名字"] = "银角大王"
    mymap["年纪"] = "三十六"
    mymap["住址"] = "沙河"
    //对map序列化
    data, err := json.Marshal(mymap)
    if err != nil {
        fmt.Printf("序列化出错:%v\n", err)
    }
    fmt.Println("序列化结果:", string(data))
}

//序列化切片
func testSlice() {
    //定义切片
    var s1 []map[string]interface{}

    var m1 map[string]interface{}

    //对map初始化
    m1 = make(map[string]interface{})
    m1["名字"] = "牛魔狗"
    m1["年纪"] = 11
    m1["地址"] = "流沙河"
    //追加切片元素
    s1 = append(s1, m1)

    //对切片序列化
    data, err := json.Marshal(s1)
    if err != nil {
        fmt.Printf("序列化出错:%v\n", err)
    }
    fmt.Println("序列化结果:", string(data))

}

func testFloat64() {
    n1 := 123.22
    data, _ := json.Marshal(n1)
    fmt.Printf("%T %v\n", string(data), string(data))

}
func main() {
    testStruct()
    testMap()
    testSlice()
    testFloat64()
    testFloat64() //对基本数据类型序列化场景较少
}

运行结果

序列化结果:{"姓名":"老王","年纪":19,"成绩":99.9}
序列化结果: {"住址":"沙河","名字":"银角大王","年纪":"三十六"}
序列化结果: [{"名字":"牛魔狗","地址":"流沙河","年纪":11}]
string 123.22
string 123.22

1.3. 反序列化

将json字符串反序列化成对应的数据类型(struct、map、slice)等。

package main

import (
    "encoding/json"
    "fmt"
)

//自定制序列化后,json字符串的key名,可以用struct的tag标签
type Student struct {
    Name  string  `json:"姓名"`
    Age   int     `json:"年纪"`
    Score float64 `json:"成绩"`
}

//反序列化结构体
func unmarshalStruct() {
    //模拟接收到的json数据,本地需要转义
    jsonStr := "{\"姓名\":\"老王\",\"年纪\":19,\"成绩\":99.9}"

    //定义Stu实例
    var stu Student
    //反序列化接收字节切片,以及空接口类型
    err := json.Unmarshal([]byte(jsonStr), &stu)

    if err != nil {
        fmt.Printf("反序列化出错:%v\n", err)
    }
    fmt.Printf("反序列化结果:stu=%v stu.Name=%v stu.Age=%v stu.Score=%v\n", stu, stu.Name, stu.Age, stu.Score)
}

//反序列化map
func unmarshalMap() {

    mapStr := "{\"住址\":\"沙河\",\"名字\":\"银角大王\",\"年纪\":\"三十六\"}"

    //定义变量 接收反序列化数据
    var m1 map[string]interface{}

    //反序列化不需要对map进行make,unmarshal函数已经封装make初始化
    err := json.Unmarshal([]byte(mapStr), &m1)
    if err != nil {
        fmt.Printf("反序列化出错:%v\n", err)
    }
    fmt.Printf("反序列化结果:%v\n", m1)

}

//反序列化切片
func unmarishalSlice() {
    sliceStr := "[{\"名字\":\"牛魔狗\",\"地址\":\"流沙河\",\"年纪\":11}]"

    var slice []map[string]interface{}
    //切片也不需要在这里make,json.Unmarishal已经封装好make
    err := json.Unmarshal([]byte(sliceStr), &qslice)
    if err != nil {
        fmt.Println("反序列化出错了,", err)
    }
    fmt.Printf("反序列化结果是:%v\n", slice)
}

func main() {
    unmarshalStruct()
    unmarshalMap()
    unmarishalSlice()
}
posted @ 2019-07-27 21:51  笑得好美  阅读(147)  评论(0编辑  收藏  举报