Golang 中正确使用omitempty 和 json

在不使用omitempty时,使用json包来对json数据进行处理

package main

import (
    "encoding/json"
    "fmt"
)
type Stu struct {
    Name  string `json:"name"`
    Age   int
    Class *Class `json:"class"`
}
type Class struct {
    Name  string
    Grade int
}
func main() {
    //实例化一个数据结构,用于生成json字符串
    stu := Stu{
        Name: "张三",
        Age:  18,
    }
    //指针变量
    cla := new(Class)
    cla.Name = "1班"
    cla.Grade = 3
    stu.Class = cla

    //jsonStu是一个byte数组,注意转换的时候,如果有json标签就会按json标签的值,没有的话就按默认值,比如json的Age就是大写
    jsonStu, _ := json.Marshal(stu)
    fmt.Println(string(jsonStu)) //{"name":"张三","Age":18,"class":{"Name":"1班","Grade":3}}

    m := make(map[string]interface{})
    //可以直接把一个json byte数组转为map(记住Unmarshal一定要通过指针接收)
    json.Unmarshal(jsonStu, &m) //map[Age:18 class:map[Grade:3 Name:1班] name:张三]
    fmt.Println(m)
    //如果要获得,map里面的map的字段就需要我们用强转符
    fmt.Println(m["class"].(map[string]interface{})["Name"]) //1班
}

小tips:struct里面包struct尽量用指针(养成习惯),防止在赋值过程中值丢失,至于其他基础类型应应该尽量用指针(实际项目中都是传递的指针看起来影响不大,但是在如果某些字段值太大,指针应该提升性能)

omitempty主要辅助json数据或者bson数据到结构体的映射

没有omitempty,当json或者bson中没有对应字段时,结构体中仍然会出现空值。同时在结构体转为json数据时,如果结构体中没有给值,会往json中传递很多空值。

用emitempty可以可以减少无效数据的传递,同时非常方便我们的映射关系

小tips,如果结构体里包含的结构体也想用emitempty,那么一定要定义为结构指针,不然emitempty不起作用。(与上一个tips呼应,如果结构体里包了结构体,无脑指针就完事了)

在使用emitempty以后,实际项目中如果不查错,可能会很多结构体没有key,在拿结构体key的时候就需要判断是否为nil 

 omitempty使用后,string类型的空值和int类型的0值都会导致无法映射出值

关于如何映射,底层使用Go反射,具体参见

https://www.cnblogs.com/smallJunJun/p/13406125.html 

json对空数组映射 (之前遇到的一个bug)

func C() (D []*A) {
    json.Unmarshal([]byte(""), &D)
    fmt.Println(D == nil) //true

    json.Unmarshal([]byte("[]"), &D)
    fmt.Println(D == nil) //false

    bytes, _ := json.Marshal(D)
    fmt.Println(string(bytes)) //null

    D = []*A{}
    bytes, _ = json.Marshal(D)
    fmt.Println(string(bytes)) //[]

    return
}

 

posted @ 2020-09-18 01:34  LeeJuly  阅读(2264)  评论(0编辑  收藏  举报