一、介绍

官方文档 https://pkg.go.dev/encoding/json 有介绍

  • omitempty如果字段的值为空值(定义为 false、0、nil 指针、nil 接口值以及任何空数组、切片、映射或字符串),该选项在编码期间忽略该字段
  • "-"标签在编码和解码时总是省略字段

二、omitempty空值省略

2.1 json在结构体重的写法

我们经常看到如下的结构体中,用tag标注了解析json的格式
首先我们初始化一个空结构体Product

package json

import (
    "encoding/json"
    "testing"
)

type Product struct {
    OrderId  string    `json:"order_id"`
    CommentS []Comment `json:"comment_s"`
}

type Comment struct {
    Id      int
    Content string
}

func TestJson(t *testing.T) {
    p := Product{}
    s, _ := json.Marshal(p)
    t.Logf("%+v", p)
    t.Log(string(s))
}

输出如下:

{OrderId: CommentS:[]} //p结构体
{"order_id":"","comment_s":null} //p的json对象

我们发现空结构是有值的!!!
和我们预想的,一个空结构,对应一个空json {}有点不一样。
是因为go中的结构体,都会有一个默认值的空值。
如果空值省略??
用 omitempty,代码修改如下:

package json

import (
    "encoding/json"
    "testing"
)

type Product struct {
    OrderId  string    `json:"order_id,omitempty"`
    CommentS []Comment `json:"comment_s,omitempty"`
}

type Comment struct {
    Id      int
    Content string
}

func TestJson(t *testing.T) {
    p := Product{}
    s, _ := json.Marshal(p)
    t.Logf("%+v", p)
    t.Log(string(s))
}

输出如下:

{OrderId: CommentS:[]} //p空结构体
{}                     //p的空json对象

如果结构体里面包含结构体呢?如何省略,示例如下:

package json

import (
    "encoding/json"
    "testing"
)

type Product struct {
    OrderId    string    `json:"order_id,omitempty"`
    CommentS   []Comment `json:"comment_s,omitempty"`
    OneComment Comment   `json:"one_comment,omitempty"`
}

type Comment struct {
    Id      int    `json:"id"`
    Content string `json:"content"`
}

func TestJson(t *testing.T) {
    p := Product{}
    s, _ := json.Marshal(p)
    t.Logf("%+v", p)
    t.Log(string(s))
}

输出如下:

{OrderId: CommentS:[] OneComment:{Id:0 Content:}} //p空结构体
{"one_comment":{"id":0,"content":""}}  //p的空json对象

我们发现json不再是 {}了 one_comment 还是展示了,为啥?
因为 OneComment 结构体的零值,是一个 Comment 结构体

type Comment struct {
    Id      int    `json:"id"`
    Content string `json:"content"`
}

而Comment的Id,和Content并没有零值省略。我们加上omitempty

package json

import (
    "encoding/json"
    "testing"
)

type Product struct {
    OrderId    string    `json:"order_id,omitempty"`
    CommentS   []Comment `json:"comment_s,omitempty"`
    OneComment Comment   `json:"one_comment,omitempty"`
}

type Comment struct {
    Id      int    `json:"id,omitempty"`
    Content string `json:"content,omitempty"`
}

func TestJson(t *testing.T) {
    p := Product{}
    s, _ := json.Marshal(p)
    t.Logf("%+v", p)
    t.Log(string(s))
}

输出如下:

{OrderId: CommentS:[] OneComment:{Id:0 Content:}}
{"one_comment":{}}

我们发现 并不是{},即使全部加上omitempty,包含的

OneComment Comment   `json:"one_comment,omitempty"`

并不是{},而是"one_comment":{}

还记得官方文档吗,并没有空结构体

omitempty如果字段的值为空值
(定义为 false、0、nil指针、nil接口值以及空数组、切片、map或字符串)
该选项在编码期间忽略该字段。

此时我们改成 空结构变成空指针 OneComment Comment*

OneComment *Comment   `json:"one_comment,omitempty"`

变成

package json

import (
    "encoding/json"
    "testing"
)

type Product struct {
    OrderId    string    `json:"order_id,omitempty"`
    CommentS   []Comment `json:"comment_s,omitempty"`
    OneComment *Comment   `json:"one_comment,omitempty"`
}

type Comment struct {
    Id      int    `json:"id,omitempty"`
    Content string `json:"content,omitempty"`
}

func TestJson(t *testing.T) {
    p := Product{}
    s, _ := json.Marshal(p)
    t.Logf("%+v", p)
    t.Log(string(s))
}

输出如下:

{OrderId: CommentS:[] OneComment:<nil>}
{}   //p的空json

谢谢您的观看,欢迎关注我的公众号。

image.png


海生
104 声望32 粉丝

与黑夜里,追求那一抹萤火。