Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go 零值 空值

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

作者:凉凉的知识库

本文主要介绍了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标签的判断逻辑如下:

对于空结构体、所有字段都为默认值的零值结构体、以及一些实际含义为零的结构体(例如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选项指定如果字段值为零,则该结构体字段应被省略

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 零值 空值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文