Go语言omitempty选项的实现

作者:黎明? 时间:2024-04-25 15:12:40 

在使用Golang的时候,不免会使用Json和结构体的相互转换,这时候常用的就是 json.Marshal 和 json.Unmarshal 两个函数。这时候在定义json结构体的时候,我们会用到 omitempty 这个字段,这个字段作用就是 空值省略,看似简单,但是却有很多小坑,这篇文章带你稍微研究一下他的用途和功能。

omit:

v. 删除; 忽略; 漏掉; 遗漏; 不做; 未能做;

adj. 省略了的;省去的;

基本用法

当我们设置json的struct的时候,会定义每个字段对一个json的格式,比如定义一个dog 结构体:

type Dog struct {
   Name   string
   Weight int
}

现在我们对他进行初始化,将其编码为JSON格式:

func main() {
   d := Dog{
       Name:   "小黑",
       Weight: 20,
   }
   marshalDog, err := json.Marshal(d)
   if err != nil {
       fmt.Println(err.Error())
   }
   fmt.Println(string(marshalDog))
}

则输出的结果为:

{"Name":"小黑","Weight":20} 

现在假如有一个结构体变量我们没初始化,那么结果可能也会跟我们预期的不太一样:

d := Dog{
       Name: "小黑",
   }

输出的结果为:

{"Name":"小黑","Weight":0}

很明显,狗的weight是未知,而不是0,并不是我们想要的结果,我们更想要的结果是:

{"Name":"小黑"}

为了实现这样的目的,我们这时候应该使用 omitempty 选项来帮我们实现,当我们在Dog结构体加上这个tag的时候:

type Dog struct {
   Name   string
   Weight int `json:",omitempty"`
}

此时,输出结果为:

{"Name":"小黑"}

不能单纯使用omitempty

当结构体相互嵌套的时候,那么omitempty就可能出现问题,比如:

type Variety struct {
    Color    string
    Category string
}
type Dog struct {
    Name    string
    Weight  int     `json:",omitempty"`
    Variety Variety `json:",omitempty"`
}
func main() {
    d := Dog{
        Name: "小黑",
    }
    marshalDog, err := json.Marshal(d)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(string(marshalDog))
}

输出结果为:

{"Name":"小黑","Variety":{"Color":"","Category":""}}

omitempty 为什么对嵌套结构体不生效呢?这是因为GO只知道简单结构体例如int,string,pointer 这种类型的空值,不知道Variety类型的空值是什么,为了不显示我们没有提供值的自定义结构体,我们可以使用结构体指针:

type Dog struct {
   Name    string
   Weight  int      `json:",omitempty"`
   Variety *Variety `json:",omitempty"`
}

运行结果为:

{"Name":"小黑"}

但是如果给出下面情况的赋值:

d := Dog{
       Name:    "小黑",
       Variety: &Variety{Color: "black"},
   }

运行结果为:

{"Name":"小黑","Variety":{"Color":"black","Category":""}}

可以看到,omitempty只对*Variety生效。所以想要嵌套结构体里面的字段也能有空值省略的效果,就要在定义嵌套的结构体的时候,对里面的每个字段都要加上omitempty选项。如下所示:

type Variety struct {
   Color    string `json:",omitempty"`
   Category string `json:",omitempty"`
}

运行结果如下:

{"Name":"小黑","Variety":{"Color":"black"}}

剩下的最后一个坑就是:如果想要某个值就是为空(有实际意义),也就是说当一个空值有实际意义的时候就显示,没有实际意义(当时还不知道其值)的时候就不显示,这样的需求应该怎么做?如果还是向上面那样,当我们需要Category为空的时候(Category:“”),最后会发现omitempty选项会把这个空值字段省略。正确的做法是使用指针来定义其变量。最后代码如下:

package main
import (
    "encoding/json"
    "fmt"
)
type Variety struct {
    Color    *string `json:",omitempty"`
    Category *string `json:",omitempty"`//一定要是*string类型
}
type Dog struct {
    Name    string
    Weight  int      `json:",omitempty"`
    Variety *Variety `json:",omitempty"`
}
func main() {
    color := "black"
    //此处的空值有实际意义
    category := ""
    d := Dog{
        Name:    "小黑",
        Variety: &Variety{Color: &color, Category: &category},
    }
    marshalDog, err := json.Marshal(d)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(string(marshalDog))
}

运行结果如下:

{"Name":"小黑","Variety":{"Color":"black","Category":""}}

来源:https://blog.csdn.net/qq_54015483/article/details/130051713

标签:Go语言,omitempty
0
投稿

猜你喜欢

  • Python时间序列缺失值的处理方法(日期缺失填充)

    2023-04-13 07:39:18
  • Oracle中查询本月星期5的所有日期列表的语句

    2012-07-11 16:13:21
  • BootStrap3学习笔记(一)之网格系统

    2024-04-29 13:43:48
  • Python的Flask项目中获取请求用户IP地址 addr问题

    2021-09-08 08:38:47
  • 基于Python 函数和方法的区别说明

    2023-10-03 02:04:01
  • Python基础知识学习之类的继承

    2022-09-02 15:41:05
  • 使用Dajngo 通过代码添加xadmin用户和权限(组)

    2021-08-07 17:43:59
  • 解决Extjs下拉框不显示的问题

    2024-04-26 17:13:00
  • Bootstrap风格的WPF样式

    2024-05-02 17:32:17
  • Python+Plotly绘制精美的数据分析图

    2022-01-09 13:02:05
  • 在ASP.NET 2.0中操作数据之十二:在GridView控件中使用TemplateField

    2023-07-07 07:02:50
  • 从ASP过渡到ASP.net遗留的二十个积习

    2024-06-05 09:26:33
  • Python使用UDP实现720p视频传输的操作

    2023-12-04 09:32:49
  • Python设计足球联赛赛程表程序的思路与简单实现示例

    2023-05-02 20:58:05
  • Python json转字典字符方法实例解析

    2021-06-07 11:21:40
  • 用户体验的另一种认识

    2007-10-25 12:36:00
  • Python安装selenium包详细过程

    2023-04-12 00:05:31
  • 一文详解Python灰色预测模型实现示例

    2023-05-11 01:45:21
  • 几款Python编译器比较与推荐(小结)

    2022-07-21 01:31:56
  • 关于pycharm找不到MySQLdb模块的解决方法

    2024-01-13 01:51:20
  • asp之家 网络编程 m.aspxhome.com