首页 > 文章列表 > Golang 中 omitempty的作用

Golang 中 omitempty的作用

golang
355 2022-12-17

前言

在尝试将结构体序列化为 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

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