在不使用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 }