zoukankan      html  css  js  c++  java
  • golang json处理

    写的几个golang json序列化和反序列化的demo,比较适合小白。

    序列化:

     1)简单的数据结构:

    package main
    
    import (
        "encoding/json"
        "fmt"
        "reflect"
    )
    
    type School struct {
        Name     string     `json:"name"`
        Location string     `json:"location"`
    }
    
    func main()  {
        school := School{
            Name:     "某某学校",
            Location: "市区",
        }
    
        str, err := json.Marshal(school)
    
        if err !=nil {
            fmt.Printf("json序列化失败%v", err)
        }
    
        fmt.Println(str)    //返回结果[123 34 110 97 109 101 34 58 34 230 159 144 230 159 144 229 173 166 230 160 161 34 44 34 108 111 99 97 116 105 111 110 34 58 34 229 184 130 229 140 186 34 125]
        fmt.Println(reflect.TypeOf(str))    //返回结果[]uint8
        fmt.Println(string(str))    //返回结果{"name":"某某学校","location":"市区"}
    }

    解释一下demo中最后为什么要经过string转换一个才能打印出最后的结果:json.Marshal最后返回的结果是byte类型的切片结果,byte和string是可以相互转换的。

    2)结构体嵌套:  

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Classroom struct {
        Number int64    `json:"number"`
        Floor  int32    `json:"floor"`
    }
    
    type School struct {
        Name     string     `json:"name"`
        Location string     `json:"location"`
        Classroom Classroom `json:"classroom"`
    }
    
    func main()  {
        school := School{
            Name:      "某某学校",
            Location:  "市区",
            Classroom:Classroom{
                Number: 201,
                Floor:  2,
            },
        }
    
        str, err := json.Marshal(school)
    
        if err !=nil {
            fmt.Printf("json序列化失败%v", err)
        }
    
        fmt.Println(string(str))    //返回结果 {"name":"某某学校","location":"市区","classroom":{"number":201,"floor":2}}
    }

    school中嵌套一个classroom的结构体,初始化赋值后便可以直接序列化。

    3)不定义结构体的做法:

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    func main()  {
        school := map[string]interface{}{
            "name" : "某某学校",
            "location" : "市区",
            "classroom" : map[string]interface{}{
                "number" : 201,
                "floor" : 2,
            },
        }
    
        str, err := json.Marshal(school)
    
        if err !=nil {
            fmt.Printf("json序列化失败%v", err)
        }
    
        fmt.Println(string(str))    //返回结果 {"name":"某某学校","location":"市区","classroom":{"number":201,"floor":2}}
    }

    可以直接初始化赋值后序列化。

    反序列化

    1)简单结构:

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Classroom struct {
        Number int64    `json:"number"`
        Floor  int32    `json:"floor"`
    }
    
    type School struct {
        Name     string     `json:"name"`
        Location string     `json:"location"`
        Classroom Classroom `json:"classroom"`
    }
    
    func main()  {
        str := `{"name":"某某学校","location":"市区","classroom":{"number":201,"floor":2}}`
        var school School
        json.Unmarshal([]byte(str), &school)    //func Unmarshal(data []byte, v interface{}) error {
        fmt.Println(school)    //返回结果 {某某学校 市区 {201 2}}
        fmt.Printf(`name:%s, location:%s, classroom:%v, number:%d, floor:%d`,
            school.Name, school.Location, school.Classroom, school.Classroom.Number, school.Classroom.Floor)    //name:某某学校, location:市区, classroom:{201 2}, number:201, floor:2
    }

    Unmarshal 传值第一个参数需要传一个byte的切片过去不能直接传str类型,str类型和byte是可以相互转化的。前面的例子序列化的时候返回的结果也是byte类型,是我们自己转换成str的。

    第二个参数需要传个结构体指针过去,如果直接传值的话,序列化的是个副本得不到最终的结果。

    2)直接反序列化

    package main
    
    import (
        "encoding/json"
        "fmt"
        "reflect"
    )
    
    func main()  {
        str := `{"name":"某某学校","location":"市区","classroom":{"number":201,"floor":2}}`
        var school interface{}
        json.Unmarshal([]byte(str), &school)    //func Unmarshal(data []byte, v interface{}) error {
        fmt.Println(school)    //返回结果 map[classroom:map[floor:2 number:201] location:市区 name:某某学校]
        //fmt.Println(school.name)    //编译报错 school.name undefined (type interface {} is interface with no methods)
        //fmt.Println(school["name"])    //编译报错 invalid operation: school["name"] (type interface {} does not support indexing)
    
        val, ok := school.(map[string]interface{})
    
        if !ok {
            fmt.Println("type is not ok")
            return
        }
    
        fmt.Println(val["name"])    //返回结果  某某学校
        fmt.Println(val["classroom"])    //返回结果 map[floor:2 number:201]
    
        //fmt.Println(val["classroom"]["number"])    //编译报错  invalid operation: val["classroom"]["number"] (type interface {} does not support indexing)
    
        classroom, ok := val["classroom"].(map[string]interface{})
    
        if !ok {
            fmt.Println("type is not ok")
            return
        }
    
        fmt.Println(classroom["number"])    //返回结果 201
        fmt.Println(reflect.TypeOf(classroom["number"]))    //返回结果 float64
    }

    如果不想定义数据结构,可以先定义一个空接口直接反序列化,但是反序列化后直接取值会编译错误,所以要先断言一下map类型。

  • 相关阅读:
    记一次Redis+Getshell经验分享
    冰蝎动态二进制加密WebShell基于流量侧检测方案
    ubuntu16下安装mongodb 3.6
    centos安装sass环境必看
    CLR 调试体系结构
    CLR 调试概述
    CLR Exception---E0434352
    关于System.MissingMethodException异常
    关于异常System.ArgumentException
    从.NET/CLR返回的hresult:0x8013XXXX的解释
  • 原文地址:https://www.cnblogs.com/smallbo/p/12318282.html
Copyright © 2011-2022 走看看