Golang 中 omitempty的作用

目录
  • 前言
  • Talk is cheap. Show me the code.
  • TestNotOmitEmpty
  • TestOmitEmptyWithDefaultValue
  • testOmitEmptyWithDefaultValueButFatherSet
  • testOmitEmptyWithNotDefaultValueButFatherSet

前言

在尝试将结构体序列化为 Json 时,你可能会遇到 “omitempty” 标记,本小记就来浅看一下它如何起作用。

先上结论:

  • 基本类型的默认值会被 omit,除了数组。
  • 指针类型为 nil 时会被 omit。

Talk is cheap. Show me the code.

package main
import (
   "encoding/json"
   "errors"
   "fmt"
)
type TestNotOmitEmpty struct {
   Uint8   uint8   `json:"uint8"`
   Uint16  uint16  `json:"uint16"`
   Uint32  uint32  `json:"uint32"`
   Uint64  uint64  `json:"uint64"`
   Int8    int8    `json:"int8"`
   Int16   int16   `json:"int16"`
   Int32   int32   `json:"int32"`
   Int64   int64   `json:"int64"`
   Int     int     `json:"int"`
   Float32 float32 `json:"float32"`
   Float64 float64 `json:"float64"`
   // Complex64     complex64      `json:"complex64"` // json: unsupported type
   // Complex128    complex128     `json:"complex128"` // json: unsupported type
   Byte          byte           `json:"byte"`
   Rune          rune           `json:"rune"`
   Uintptr       uintptr        `json:"uintptr"`
   String        string         `json:"string"`
   StringPointer *string        `json:"stringPointer"`
   Array         [10]int        `json:"array"`
   Slice         []int          `json:"slice"`
   Map           map[int]string `json:"map"`
   // Channel       chan int       `json:"channel"` // json: unsupported type
   Interface interface{} `json:"interface"`
   Error     error       `json:"error"`
}

type TestOmitEmptyWithDefaultValue struct {
   Uint8   uint8   `json:"uint8,omitempty"`
   Uint16  uint16  `json:"uint16,omitempty"`
   Uint32  uint32  `json:"uint32,omitempty"`
   Uint64  uint64  `json:"uint64,omitempty"`
   Int8    int8    `json:"int8,omitempty"`
   Int16   int16   `json:"int16,omitempty"`
   Int32   int32   `json:"int32,omitempty"`
   Int64   int64   `json:"int64,omitempty"`
   Int     int     `json:"int,omitempty"`
   Float32 float32 `json:"float32,omitempty"`
   Float64 float64 `json:"float64,omitempty"`
   // Complex64     complex64      `json:"complex64,omitempty"` // json: unsupported type
   // Complex128    complex128     `json:"complex128,omitempty"` // json: unsupported type
   Byte          byte           `json:"byte,omitempty"`
   Rune          rune           `json:"rune,omitempty"`
   Uintptr       uintptr        `json:"uintptr,omitempty"`
   String        string         `json:"string,omitempty"`
   StringPointer *string        `json:"stringPointer,omitempty"`
   Array         [10]int        `json:"array,omitempty"`
   Slice         []int          `json:"slice,omitempty"`
   Map           map[int]string `json:"map,omitempty"`
   // Channel       chan int       `json:"channel,omitempty"` // json: unsupported type
   Interface interface{} `json:"interface,omitempty"`
   Error     error       `json:"error,omitempty"`
}

func ToStringPointer(s string) *string {
   return &s
}

func main() {
   testOmitEmpty := TestNotOmitEmpty{}
   jsonData, err := json.Marshal(testOmitEmpty)

   if err != nil {
      println(err)
      panic(err)
   }
   fmt.Printf("TestNotOmitEmpty: %s\n", jsonData)
   testOmitEmptyWithDefaultValue := TestOmitEmptyWithDefaultValue{}
   jsonData2, err := json.Marshal(testOmitEmptyWithDefaultValue)
   if err != nil {
      println(err)
      panic(err)
   }

   fmt.Printf("TestOmitEmptyWithDefaultValue: %s\n", jsonData2)

   testOmitEmptyWithDefaultValueButFatherSet := TestOmitEmptyWithDefaultValue{
      Uint8:         0,
      Uint16:        0,
      Uint32:        0,
      Uint64:        0,
      Int8:          0,
      Int16:         0,
      Int32:         0,
      Int64:         0,
      Int:           0,
      Float32:       0,
      Float64:       0,
      Byte:          0,
      Rune:          0,
      Uintptr:       0,
      String:        "",
      StringPointer: nil,
      Array:         [10]int{},
      Slice:         nil,
      Map:           nil,
      Interface:     nil,
      Error:         nil,
   }
   jsonData3, err := json.Marshal(testOmitEmptyWithDefaultValueButFatherSet)

   if err != nil {
      println(err)
      panic(err)
   }
   fmt.Printf("testOmitEmptyWithDefaultValueButFatherSet: %s\n", jsonData3)

   testOmitEmptyWithNotDefaultValueButFatherSet := TestOmitEmptyWithDefaultValue{
      Uint8:         1,
      Uint16:        1,
      Uint32:        1,
      Uint64:        1,
      Int8:          1,
      Int16:         1,
      Int32:         1,
      Int64:         1,
      Int:           1,
      Float32:       1,
      Float64:       1,
      Byte:          1,
      Rune:          1,
      Uintptr:       1,
      String:        "1",
      StringPointer: ToStringPointer(""),
      Array:         [10]int{1},
      Slice:         []int{1},
      Map:           map[int]string{1: "1"},
      Interface:     "1",
      Error:         errors.New("error"),
   }
   jsonData4, err := json.Marshal(testOmitEmptyWithNotDefaultValueButFatherSet)

   if err != nil {
      println(err)
      panic(err)
   }
   fmt.Printf("testOmitEmptyWithNotDefaultValueButFatherSet: %s\n", jsonData4)
}

TestNotOmitEmpty

全部序列化成功。

TestOmitEmptyWithDefaultValue

默认值全军覆没,除了数组。

testOmitEmptyWithDefaultValueButFatherSet

自己设置的默认值也全军覆没,除了数组。

testOmitEmptyWithNotDefaultValueButFatherSet

非默认值当然不会被省略了。

到此这篇关于Golang 中 omitempty的作用的文章就介绍到这了,更多相关Golang omitempty内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • golang中json的omitempty使用操作

    我就废话不多说了,大家还是直接看代码吧~ package main import ( "encoding/json" "fmt" ) type Project struct { Name string `json:"name"` Url string `json:"url"` Docs string `json:"docs,omitempty"` } func main() { p1 := Project{

  • Golang中omitempty关键字的具体实现

    目录 用法 陷阱 用法 熟悉 Golang 的朋友对于 json 和 struct 之间的转换一定不陌生,为了将代码中的结构体与 json 数据解耦,通常我们会在结构体的 field 类型后加上解释说明,例如在表示一个地址的时候, json 数据如下所示 { "street": "200 Larkin St", "city": "San Francisco", "state": "CA"

  • Golang 中 omitempty的作用

    目录 前言 Talk is cheap. Show me the code. TestNotOmitEmpty TestOmitEmptyWithDefaultValue testOmitEmptyWithDefaultValueButFatherSet testOmitEmptyWithNotDefaultValueButFatherSet 前言 在尝试将结构体序列化为 Json 时,你可能会遇到 “omitempty” 标记,本小记就来浅看一下它如何起作用. 先上结论: 基本类型的默认值会被

  • golang中context的作用详解

    当一个goroutine可以启动其他goroutine,而这些goroutine可以启动其他goroutine,依此类推,则第一个goroutine应该能够向所有其它goroutine发送取消信号. 上下文包的唯一目的是在goroutine之间执行取消信号,而不管它们如何生成.上下文的接口定义为: type Context interface { Deadline() (deadline time.Time, ok bool) Done() <- chan struct{} Err() erro

  • GoLang中Json Tag用法实例总结

    目录 前言 Json中Tag用法汇总 官方 Marshal 函数说明 参考 总结 前言 GoLang中结构体的 JSON Tag 标识(英文名backquote或backtick,反引号 ` 符号包裹的部分内容)一直未明确看过完整规范和使用说明,存在模棱两可,系统整理如下: JSON Tag标签的完整语法,包含哪些选项 不同选项(输出名/-/omitempty/string)的作用及使用范围 特殊注意事项补充 Json中Tag用法汇总 JSON Tag标签格式为:json:"FieldName/

  • golang中defer的关键特性示例详解

    前言 大家都知道golang的defer关键字,它可以在函数返回前执行一些操作,最常用的就是打开一个资源(例如一个文件.数据库连接等)时就用defer延迟关闭改资源,以免引起内存泄漏.本文主要给大家介绍了关于golang中defer的关键特性,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍: 一.defer 的作用和执行时机 go 的 defer 语句是用来延迟执行函数的,而且延迟发生在调用函数 return 之后,比如 func a() int { defer b() return

  • Golang中switch语句和select语句的用法教程

    本文主要给大家介绍了关于Golang中switch和select用法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.switch语句 switch语句提供了一个多分支条件执行的方法.每一个case可以携带一个表达式或一个类型说明符.前者又可被简称为case表达式.因此,Go语言的switch语句又分为表达式switch语句和类型switch语句. 1.表达式switch语句 var name string ... switch name { case "Golang"

  • 详解golang中bufio包的实现原理

    最近用golang写了一个处理文件的脚本,由于其中涉及到了文件读写,开始使用golang中的 io 包,后来发现golang 中提供了一个bufio的包,使用这个包可以大幅提高文件读写的效率,于是在网上搜索同样的文件读写为什么bufio 要比io的读写更快速呢?根据网上的资料和阅读源码,以下来详细解释下bufio的高效如何实现的. bufio 包介绍  bufio包实现了有缓冲的I/O.它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文

  • 浅谈Golang中创建一个简单的服务器的方法

    我们知道,golang中的net/http包对网络的支持非常好,这样会让我们比较容易的建立起一个相对简单的服务器,我们来看一段代码 func sayHi(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w,"Hi") } func main() { http.HandleFunc("/sayHi", sayHi) log.Fatal(http.ListenAndServe("localhost:80

  • 深入Golang中的sync.Pool详解

    我们通常用golang来构建高并发场景下的应用,但是由于golang内建的GC机制会影响应用的性能,为了减少GC,golang提供了对象重用的机制,也就是sync.Pool对象池. sync.Pool是可伸缩的,并发安全的.其大小仅受限于内存的大小,可以被看作是一个存放可重用对象的值的容器. 设计的目的是存放已经分配的但是暂时不用的对象,在需要用到的时候直接从pool中取. 任何存放区其中的值可以在任何时候被删除而不通知,在高负载下可以动态的扩容,在不活跃时对象池会收缩. sync.Pool首先

  • golang 中 channel 的详细使用、使用注意事项及死锁问题解析

    目录 什么是channel管道 channel的基本使用 定义和声明 操作channel的3种方式 单向channel 带缓冲和不带缓冲的channel 不带缓冲区channel 带缓冲区channel 判断channel是否关闭 rangeandclose for读取channel select使用 channel的一些使用场景 1.作为goroutine的数据传输管道 2.同步的channel 3.异步的channel 4.channel超时处理 使用channel的注意事项及死锁分析 未初

随机推荐