golang 简单的代码,以便在处理json时简化开发。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 简单的代码,以便在处理json时简化开发。相关的知识,希望对你有一定的参考价值。

imoprt "encoding/json"

func printJson(in interface{}) {
        b, _ := json.Marshal(in)
        fmt.Println(string(b))
}

func printJsonErr(in interface{}, err error) {
        if (err != nil) {
                fmt.Println(err)
        } else {
                b, _ := json.Marshal(in)
                fmt.Println(string(b))
        }
}

golang json处理

 

序列化:

 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类型。

 

以上是关于golang 简单的代码,以便在处理json时简化开发。的主要内容,如果未能解决你的问题,请参考以下文章

Golang处理JSON--- 解码

Golang解析json的特殊情况处理

如何用Golang处理每分钟100万个请求

golang快速入门JSON处理

golang图片处理水印去除

[golang]反射的用处--代码自动生成