Go中零值与空值的实现与区别

 更新时间:2026年02月26日 09:21:14   作者:凉凉的知识库  
本文主要介绍了Go中零值与空值的实现与区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

内置类型的零值/默认值

变量声明但未显式初始化时,Go 自动赋的默认值。它保证“未初始化”也有确定、可用的值

TYPEZERO VALUE
Integer0
Floating point0.0
Booleanfalse
String""
Pointernil
Interfacenil
Slicenil
Mapnil
Arrayfields zero (每个元素都是其零值)
Structfields zero (每个元素都是其零值)
Channelnil
Functionnil

Json序列化中的omitempty&omitzero

omitempty

当对一个结构体的某个字段的tag设置为omitempty时,如果这个字段是空值(empty value,和零值不一样)时,那么这个字段就会在序列化时省略

The “omitempty” option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string.

omitempty标签的判断逻辑如下:

  • 对于布尔类型:false被视为空
  • 对于数值类型:0被视为空
  • 对于指针、接口:nil被视为空
  • 对于字符串:""(空字符串)被视为空
  • 对于数组、切片、map:长度为0被视为空,既包含未初始化的又包含空的

对于空结构体、所有字段都为默认值的零值结构体、以及一些实际含义为零的结构体(例如time.Time{}),omitempty都无能为力,会进行输出。

因此在Go 1.24之前想对某个结构体不输出,可选的一种方案是使用指针类型

type VanillaStruct struct {
    StructTyp1 struct{}        // 空结构体
    StructTyp2 struct{ A int } // 零值结构体
    TimeTyp    time.Time       // 实际含义为零的结构体
​
    StructTyp3 *struct{}
    StructTyp4 *struct{ A int }
    TimeTyp2   *time.Time
}
​
type OmitemptyStruct struct {
    StructTyp1 struct{}        `json:",omitempty"`
    StructTyp2 struct{ A int } `json:",omitempty"`
    TimeTyp1   time.Time       `json:",omitempty"`
​
    StructTyp3 *struct{}        `json:",omitempty"`
    StructTyp4 *struct{ A int } `json:",omitempty"`
    TimeTyp2   *time.Time       `json:",omitempty"`
}
​
func main() {
    s1 := VanillaStruct{}
    ss1, err := json.Marshal(s1)
    fmt.Println(err, string(ss1)) 
    // {"StructTyp1":{},"StructTyp2":{"A":0},"TimeTyp":"0001-01-01T00:00:00Z","StructTyp3":null,"StructTyp4":null,"TimeTyp2":null}
​
    s2 := OmitemptyStruct{}
    ss2, err := json.Marshal(s2)
    fmt.Println(err, string(ss2)) 
    // {"StructTyp1":{},"StructTyp2":{"A":0},"TimeTyp1":"0001-01-01T00:00:00Z"}
}

omitzero

Go 1.24 给 encoding/json 新增omitzero:按零值(zero value)省略

在序列化时,omitzero选项指定如果字段值为零,则该结构体字段应被省略

  • 如果该类型定义了IsZero() bool方法,那么这个零值就通过IsZero方法来判断
  • 否则是根据字段是否是零值(通过reflect.Value.IsZero判断)来判断
type VanillaStruct struct {
    StructTyp1 struct{}        // 空结构体
    StructTyp2 struct{ A int } // 零值结构体
    TimeTyp    time.Time       // 实际含义为零的结构体
}
​
type OmitzeroStruct struct {
    StructTyp1 struct{}        `json:",omitzero"`
    StructTyp2 struct{ A int } `json:",omitzero"`
    TimeTyp1   time.Time       `json:",omitzero"`
}
​
func main() {
    s1 := VanillaStruct{}
    ss1, err := json.Marshal(s1)
    fmt.Println(err, string(ss1))
    // {"StructTyp1":{},"StructTyp2":{"A":0},"TimeTyp":"0001-01-01T00:00:00Z"}
​
    s2 := OmitzeroStruct{}
    ss2, err := json.Marshal(s2)
    fmt.Println(err, string(ss2))
    // {}
}

总结

下面是一个完整的Go示例,展示了omitempty&omitzero标签在不同类型上的应用:

TYPEZERO VALUEEMPTY VALUEWITHOUT OMITOMITEZEROOMITEMPTY
Integer000OMITOMIT
Floating point000OMITOMIT
BooleanFALSEFALSEFALSEOMITOMIT
String""""""OMITOMIT
PointernilnilnullOMITOMIT
InterfacenilnilnullOMITOMIT
SlicenilnilnullOMITOMIT
Slicenilmake([]T, 0)[][]OMIT
MapnilnilnullOMITOMIT
Mapnilmake(map[K]V, 0){}{}OMIT
Array: [0]Tfields zero[0]T[]OMITOMIT
Array: [N]Tfields zero[T]OMIT[T]
Struct: struct{}fields zero{}OMIT{}
Struct: struct{ F T }fields zero{"F": T}OMIT{"F": T}
Channelnilnil
Functionnilnil

到此这篇关于Go中零值与空值的实现与区别的文章就介绍到这了,更多相关Go 零值 空值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言读取YAML 配置文件的两种方式分享

    Go语言读取YAML 配置文件的两种方式分享

    在日常开发中,YAML 格式的文件基本上被默认为是配置文件,其内容因为缩进带来的层级感看起来非常直观和整洁。本文分享了读取YAML 配置文件的两种方式,需要的可以参考一下
    2022-12-12
  • 一文带你掌握Go语言中的文件读取操作

    一文带你掌握Go语言中的文件读取操作

    这篇文章主要和大家分享一下Go语言中的文件读取操作,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的小伙伴可以参考一下
    2022-12-12
  • 基于Golang设计一套可控的定时任务系统

    基于Golang设计一套可控的定时任务系统

    这篇文章主要为大家学习介绍了如何基于Golang设计一套可控的定时任务系统,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-07-07
  • 一文详解Go语言中的Defer机制

    一文详解Go语言中的Defer机制

    在Go语言中,defer是一个关键字,用于确保资源的清理和释放,特别是在函数中创建的资源,下面就跟随小编一起来了解下Defer机制的具体使用吧
    2024-11-11
  • go语言beego框架分页器操作及接口频率限制示例

    go语言beego框架分页器操作及接口频率限制示例

    这篇文章主要为大家介绍了go语言beego框架分页器操作使用示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go语言学习之golang-jwt/jwt的教程分享

    Go语言学习之golang-jwt/jwt的教程分享

    jwt是 json web token的简称。go使用jwt目前,主流使用的jwt库是golang-jwt/jwt。本文就来和大家讲讲golang-jwt/jwt的具体使用,需要的可以参考一下
    2023-01-01
  • Go语言实现将中文转化为拼音功能

    Go语言实现将中文转化为拼音功能

    这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-01-01
  • go的defer和闭包示例说明(非内部实现)

    go的defer和闭包示例说明(非内部实现)

    这篇文章主要为大家介绍了go的defer和闭包示例说明(非内部实现),有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Go 连接 MySQL之 MySQL 预处理详解

    Go 连接 MySQL之 MySQL 预处理详解

    Go语言提供了丰富的库和工具,可以方便地连接MySQL数据库。MySQL预处理是一种提高数据库操作效率和安全性的技术。Go语言中的第三方库提供了MySQL预处理的支持,通过使用预处理语句,可以避免SQL注入攻击,并且可以提高数据库操作的效率。
    2023-06-06
  • gin session中间件使用及源码流程分析

    gin session中间件使用及源码流程分析

    这篇文章主要为大家介绍了gin session中间件使用及源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10

最新评论