golang omitempty 总结

当我们设置json的struct的时候,会定义每个字段对一个json的格式,比如定义一个dog 结构体:

type Dog struct {
Breed string
WeightKg int
}
现在我们对他进行初始化,将其编码为JSON格式:

func main() {
d := Dog{
Breed: “dalmation”,
WeightKg: 45,
}
b, _ := json.Marshal(d)
fmt.Println(string(b))
}
则输出的结果为:{“Breed”:“dalmation”,“WeightKg”:45},你可点击这里.

现在假如有一个结构体变量我们没初始化,那么结果可能也会跟我们预期的不太一样:

func main() {
d := Dog{
Breed: “pug”,
}
b, _ := json.Marshal(d)
fmt.Println(string(b))
}
输出的结果为:{“Breed”:“pug”,“WeightKg”:0},明显dog的weight是未知,而不是0,并不是我们想要的结果,我们更想要的结果是:“WeightKg”:null。

为了实现这样的目的,我们这时候应该使用omitempty 变量来帮我们实现,当我们在Dog结构体加上这个tag的时候:

type Dog struct {
Breed string
// The first comma below is to separate the name tag from the omitempty tag
WeightKg int json:",omitempty"
}
输出结果为:{“Breed”:“pug”}。现在WeightKg就被设置为默认零值(对于int应该为0,对于string应该为"", 指针的话应该为nil)。

不能单纯使用omitted
当结构体相互嵌套的时候,那么omitempty就可能出现问题,比如:

type dimension struct {
Height int
Width int
}

type Dog struct {
Breed string
WeightKg int
Size dimension json:",omitempty"
}

func main() {
d := Dog{
Breed: “pug”,
}
b, _ := json.Marshal(d)
fmt.Println(string(b))
}
输出结果为:

{“Breed”:“pug”,“WeightKg”:0,“Size”:{“Height”:0,“Width”:0}}
我们已经使用omitempty标注的dimension还是显示了出来。这是因为结构体dimension不知道空值是什么,GO只知道简单结构体例如int,string,pointer 这种类型的空值,为了不显示我们没有提供值的自定义结构体,我们可以使用结构体指针:

type Dog struct {
Breed string
WeightKg int
// Now Size is a pointer to a dimension instance
Size *dimension json:",omitempty"
}
运行结果为:

{“Breed”:“pug”,“WeightKg”:0}
为什么会这样呢?因为指针是基本类型啊,Golang知道他的空值是啥,所以就直接赋值为nil(指针类型的空值)。

现在出一个问题,下面的程序的初始结果是什么?

type Dog struct {
Age *int json:",omitempty"
}

func main() {
age := 0
d := Dog{
Age: &age,
}

b, _ := json.Marshal(d)
fmt.Println(string(b))

}
A. {“Age”:0}
B. {}
答案在最后揭晓。

0, “”, nil 三者的区别
现在很难的很区别的是:零值,值为0,默认值。

比如我们设置一个restaurant结构体:

type Restaurant struct {
NumberOfCustomers int json:",omitempty"
}

func main() {
d := Restaurant{
NumberOfCustomers: 0,
}
b, _ := json.Marshal(d)
fmt.Println(string(b))
}
他的输出结果为:

{}
这肯定不是我们想要的结果,因为这个时候我们想要他输出0,他却没有任何值输出。因为Golang把0当成了零值,所以跟没有赋值是一样的,比如:

type Restaurant struct {
NumberOfCustomers int json:",omitempty"
Name string
}

func main() {
d := Restaurant{
//给NumberOfCustomers赋值
NumberOfCustomers: 0,
Name: “hello”,
}
b, _ := json.Marshal(d)
fmt.Println(string(b))
}

type Restaurant struct {
NumberOfCustomers int json:",omitempty"
Name string
}

func main() {
d := Restaurant{
//未给NumberOfCustomers赋值
Name: “hello”,
}
b, _ := json.Marshal(d)
fmt.Println(string(b))
}
二者结果都是:{“Name”:“hello”}

解决这样的问题的一种方法是使用int指针,因为int指针的空值为nil,当我想输出0的时候,我传进去地址,地址肯定不是空值nil,这样肯定会显示出来0.

type Restaurant struct {
NumberOfCustomers *int json:",omitempty"
}

func main() {
d1 := Restaurant{}
b, _ := json.Marshal(d1)
fmt.Println(string(b))
//Prints: {}

n := 0
d2 := Restaurant{
	NumberOfCustomers: &n,
}
b, _ = json.Marshal(d2)
fmt.Println(string(b))
//Prints: {"NumberOfCustomers":0}

}
亚马逊测评 www.yisuping.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值