Go - 37 Go Json的序列化/反序列化 应用

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。同时也易于机器解析和生成;key-val
    JSON是在2001年开始推广使用的数据格式,目前已经成为主流的数据格式。
    JSON易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络传输时会先将数据(结构体/map等)序列化成json字符串,到接收方得到json字符串时,在反序列化恢复成原来的数据类型(结构体/map等)。这种方式已然成为各个语言的标准。
 
    JSON应用场景:
    web编程中应用 : B/S 架构
    tcp编程中的应用:聊天系统  C/S 架构
 
    JSON数据格式说明:
    在js语言中,一切都是对象,因此,任何的数据类型都可以通过JSON来表示,例如:字符串,数字,对象,数组,map ,结构体等。
    JSON键值对是用来保存数据一种的方式,键/值对组合中的键名写在前面并用双引号""包裹,使用冒号:分割,然后紧接着值;
    json数据在线解析网站:https://www.json.cn/
    
    Json序列化:
        json序列化是指,将有key-value结构的数据类型(比如结构体,map,切片)序列化成json字符串的操作
        操作案例:
        需要用到的包:"encoding/json"
        // 定义一个结构体 + tag标签(反射机制)(Marshal--序列化数据会涉及跨包使用,所以得用大写,然后加tag标签)
        type Monster struct {     
                Name string `json:"name"`    
                Age int   `json:"age"`
                // Name string  
                // Age int      
                Birthday string      
                Sal float64     
                Skill string  
        } 
 
        // 将结构体序列化
        func testStruct() {     
                m := Monster{         
                        Name: "孙悟空",         
                        Age : 500,         
                        Birthday: "2020-12-28",         
                        Sal : 20000.0,         
                        Skill : "七十二变",     
                }     
                // 将Monster 实例 序列化     
                m_slice, err := json.Marshal(&m)     
                if err != nil {         
                        fmt.Println("序列化出错==", err)     
                }     
                // 序列化后的结果     
                fmt.Println(string(m_slice)) 
        }  
 
        // 将map序列化 
        func testMap() {     
                // 定义一个map     
                var a map[string]interface{}      
                // 使用map,需要make     
                a = make(map[string]interface{})     
                a["name"] = "沙和尚"     
                a["age"] = 200     
                a["address"] = "流沙河"     
                // 将 a map类型序列化 map 本身就是引用类型,所以 不用传地址     
                a_slice, err := json.Marshal(a)     
                if err != nil {         
                        fmt.Println("a map 序列化出错=", err)     
                }     
                // a map 序列化后的结果     
                fmt.Println("a map json==", string(a_slice)) 
        } 
 
        // 将切片序列化 
        func testSlice() {     
                        // slice map 都需要make才能用     
                        var s []map[string]interface{}     
                        s = make([]map[string]interface{}, 2, 4)     
                        s[0] = make(map[string]interface{})     
                        s[0]["name"] = "tom"     
                        s[0]["age"] = 30     
                        s[0]["address"] = []string{"北京", "邯郸"}     
                        s[1] = make(map[string]interface{})     
                        s[1]["name"] = "marry"     
                        s[1]["age"] = 28     
                        s[1]["address"] = "北京"     
                        s_slice, err := json.Marshal(s)     
                        if err != nil {         
                                fmt.Println("s slice 序列化出错=", err)     
                        }     
                        // 序列化后的结果     
                        fmt.Println("s slice json=", string(s_slice)) } 
                        // 基本数据类型的序列化 
                        func baseTest() {     
                                var num1 float64 = 232423.20     
                                data, err := json.Marshal(num1)     
                                if err != nil {         
                                        fmt.Println("num1 序列化出错=", err)     
                                }     
                                // 序列化后的结果     
                                fmt.Println("num1 json=", string(data)) 
        } 
        func main() {     
                // 将结构体,map,切片 进行序列化     
                testStruct()     
                testMap()     
                testSlice()     
                // 对基本数据类型序列化在实际中意义不大     
                baseTest() 
        } 
 
Json反序列化
    json反序列化是指,将json字符串反序列化成对应的数据类型(比如结构体,map,切片)的操作。
    
    实际案例:
        // 定义一个结构体 用来解析json串
        type Monster struct {     
                Name string     
                Age int      
                Birthday string      
                Sal float64     
                Skill string  
        } 
        // 将json字符串,反序列化成struct  
        func unmarshalStruct() {     
                // str 在项目开发中,是通过网络传输获取到的,或者是读取文件获取到的     
                str := "{\"Name\":\"孙悟空\",\"Age\":500,\"Birthday\":\"2020-12-28\",\"Sal\":20000,\"Skill\":\"七十二变\"}"     
                // 定义一个Monster实例     
                var m Monster     
                // Unmarshal两个参数:第一个接收json的数据--> byte切片  第二个参数:根据json数据要改变的Monster实例                             err := json.Unmarshal([]byte(str), &m)       
                if err != nil {         
                        fmt.Println("unmarshal err=", err)     
                }     
                fmt.Println("struct 反序列化后 m=", m, m.Name) 
        } 
        // json数据 反序列化成map 
        func unmarshalMap() {     
                str := "{\"address\":\"流沙河\",\"age\":200,\"name\":\"沙和尚\"}"     
                // 定义一个map     
                var a map[string]interface{}      
                // 注意:反序列化map,不需要make,因为make操作被封装到Unmarshal 函数                                                            
                err := json.Unmarshal([]byte(str), &a)     
                if err != nil {         
                        fmt.Println("map unmarshal err==", err)     
                }     
                fmt.Println("map 反序列化后=", a) 
        } 
        // json数据,反序列化成切片 
        func unmarshalSlice() {     
                str := "[{\"address\":[\"北京\",\"邯郸\"],\"age\":30,\"name\":\"tom\"}," +      "{\"address\":\"北京\",\"age\":28,\"name\":\"marry\"}]"     
                var s []map[string]interface{}     
                err := json.Unmarshal([]byte(str), &s)     
                if err != nil {         
                        fmt.Println("slice unmarshal err=", err)     
                }     
                fmt.Println("slice 反序列化=", s) 
        } 
        func main() {     
                // unmarshal     
                unmarshalStruct()     
                unmarshalMap()     
                unmarshalSlice() 
        }
 
        小结说明:
            1.在反序列化一个json字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。
            2.如果json字符串是通过程序获取到的,则不需要再对 "" 转义处理。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2020-12-29 14:22  以赛亚  阅读(237)  评论(0编辑  收藏  举报