Golang: 让你的零值更有用
文章目录
Make the zero value useful。 –Go Proverbs
让我们从 Golang blog 开始吧:The zero value
当内存被分配来存储一个值时,无论是通过声明还是调用 make 或 new,并且没有提供明确的初始化,内存被赋予一个默认的初始化。这种值的每个元素都被设置为其类型的零值 (zero value):布尔值为 false,整数为 0,浮点数为 0.0,字符串为
""
,指针、函数、接口、slice、channel 和 map 为 nil。这种初始化是递归进行的,因此,举例来说,如果没有指定值,结构数组的每个元素都将被归零。
这样将一个值设置为零值对程序的安全性和正确性做了很大的保证,同样也能很好的保证程序的可读性与简单性。这也就是 Golang 程序员口中的“让零值更有用 (Make the zero value useful)”。
零值 cheat sheet
类型 | 零值 |
---|---|
bool | false |
int | 0 |
float | 0.0 |
string | "" |
pointer | nil |
function | nil |
slice | nil |
map | nil |
channel | nil |
同时零值的初始化是递归的,因此,如果没有指定值,结构数组的每个元素都将被归零。
|
|
对于结构体也是如此,我们初始化一个引用 A 的 B 结构体,并且没有指定值,那么 B 的每个字段都将被归零。
|
|
note:
- new:new(T) 返回一个指向新分配的 T 类型的
零值
的指针。 - 使用的工具为 gore
零值的用法
上文已经介绍了什么是零值,这里我们来看看如何使用它们。
sync.Mutex
这里有一个关于 sync.Mutex 的例子,sync.Mutex 被设计成不用显式地去初始化他就可以直接通过零值来使用。
|
|
得益于零值的特性,Mutex 内部两个未导出的变量都会被初始化为零值。所以 sync.Mutex 的零值是一个未锁定的 Mutex。
|
|
bytes.Buffer
另外一个例子是 bytes.Buffer,它的零值是一个空的 Buffer。
|
|
JSON omitempty
JSON 接收器也接受 omitempty
这个 flag,当输入的字段是 零值
时,接收器会忽略这个字段。
|
|
channel close
在《Channel Axioms》中,也有一条与零值相关的规则,当 channel 关闭时,对被关闭的 channel 做<- 操作,总是立即返回 零值
。
|
|
解决上述问题的正确的方式是使用 for loop:
|
|
map 中未找到对应 key 的 value
对于一个 map,如果没有找到对应的 key,那么这个 map 会返回对应类型一个零值。
|
|
解决这个问题的方法是返回多个值:
|
|
对于不存在的 key,ok 的 value 将会变成 false。
总结
以上就是关于 零值
的一些经验总结。希望大家在设计代码的时候能够将 零值
更好的用起来,利用 零值
提供的特性来初始化一些变量。
相关链接
文章推荐
最后最后和大家分享一些最近在看的好文,想过用周刊的方式发送但是因为看的比较零散,就放在每篇博文的最后,希望大家能够收获。
- 为什么我们不生小孩一些关于生小孩的思考
- 《The Tail At Scale》论文详细解读
- 编写可维护的 Go 代码很多观点让我在实践之后感受到共鸣,代码写出来一遍,但是会被读上百遍,所以编写可维护的代码很重要。
- Golang 并发编程进阶 talk 分享者提供了实际并发问题的,然后给出了自己的一些解决方案。非常受益。
- pprof 图解终于会看 pprof 了。
文章作者 xiantang
上次更新 2024-07-09 (9ac8718e)