Golang Cheese "omitempty"

When trying to serialize a struct to Json, you may encounter the "omitempty" tag, and this small note will take a brief look at how it works.

Conclusion first

  • Default values ​​for primitive types are omited, except for arrays.
  • A pointer of type nil will be omited.

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

All serialized successfully.

image.png

TestOmitEmptyWithDefaultValue

The default value is annihilation, except for arrays.

image.png

testOmitEmptyWithDefaultValueButFatherSet

The default values ​​you set yourself are also wiped out, except for arrays.

image.png

testOmitEmptyWithNotDefaultValueButFatherSet

Non-default values ​​are of course not omitted.

image.png

Guess you like

Origin juejin.im/post/7115343247530164254