陈明勇一名热爱技术、乐于分享的开发者,同时也是开源爱好者。
91文章
12分类
21标签
19评论
160点赞
98031浏览量
0
0
Go 1.24 新特性:JSON omitzero 标签,更清晰且可定制的零值忽略
陈明勇
2025-02-24 15:45:29
阅读 164

扫码关注公众号,手机阅读更方便

Go技术干货

前言

Go 1.24 版本中,encoding/json 包新增了 omitzero 标签,使得零值字段的忽略行为更加明确和可定制。本文将详细介绍 omitzero 标签的使用。

准备好了吗?准备一杯你最喜欢的咖啡或茶,随着本文一探究竟吧。

let's go

omitzero 标签

omitzero 标签用于在将 Go 对象序列化为 JSON 时,控制哪些 零值 字段应被忽略。与 omitempty 标签不同,omitempty 忽略的是 空值 字段,而 零值空值 虽然相似,但在 Go 中并不等价。例如:

  • 对于 time.Time 类型,零值是 "0001-01-01T00:00:00Z",这并不被视为 空值
  • 对于切片字段 IntSlice []int,当其值为 []nil 时,都会被视为 空值

为什么使用 omitzero

  • 精准控制:明确地忽略零值字段,而不是空值字段。
  • 定制化控制:通过 IsZero() bool 方法,可以自定义字段的零值判断逻辑。

omitzero 标签的使用

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type User struct {
    Name    string    `json:"name,omitzero"`
    Age     int       `json:"age,omitzero"`
    Hobbies []string  `json:"hobbies,omitzero"`
    BornAt  time.Time `json:"born_at,omitzero"`
}

func main() {
    user := User{
        Name:    "陈明勇",
        Age:     18,
        Hobbies: []string{},
    }

    bytes, _ := json.MarshalIndent(user, "", "  ")
    fmt.Println(string(bytes))
}

打印 string(bytes) 将会输出以下 json 结果:

{
  "name": "陈明勇",
  "age": 18,
  "hobbies": []
}

如果使用 omitempty 标签,hobbies 字段将被省略,而即使 born_at 是零值,依然会被序列化成 "born_at": "0001-01-01T00:00:00Z"。通过使用 omitzero 标签,我们可以更精确地控制哪些字段会被忽略,确保只有零值字段才会被排除。

IsZero() bool 方法

IsZero() bool 方法用于自定义字段的零值判断逻辑。如果你希望修改某个字段的零值的判定方式,可以为该字段实现 IsZero 方法。下面是一个示例:

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type Age int

func (age *Age) IsZero() bool {
    return *age <= 0
}

type User struct {
    Name    string    `json:"name,omitzero"`
    Age     Age       `json:"age,omitzero"`
    Hobbies []string  `json:"hobbies,omitzero"`
    BornAt  time.Time `json:"born_at,omitzero"`
}

func main() {
    user := User{
        Name:    "陈明勇",
        Age:     -1,
        Hobbies: []string{},
    }

    bytes, _ := json.MarshalIndent(user, "", "  ")
    fmt.Println(string(bytes))
}

在这个示例中,Age 字段通过实现 IsZero 方法来控制其零值判断逻辑。如果 Age 小于等于 0 时,IsZero 返回 true,该字段就会被忽略。输出结果为:

{
  "name": "陈明勇",
  "hobbies": []
}

小结

Go 语言中,通过使用 omitzero 标签,我们可以精确控制哪些字段被忽略,确保只有零值字段会被排除。同时,通过实现 IsZero 方法,我们可以自定义字段的零值判断逻辑,以满足不同的序列化需求。

0
评论
个人信息
清空
预览
提交
陈明勇一名热爱技术、乐于分享的开发者,同时也是开源爱好者。
91文章
12分类
21标签
19评论
160点赞
98031浏览量