diff --git a/README.md b/README.md index 1e0cff9..45e38f3 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Go tips from [Phuong Le](https://twitter.com/func25). | 10 | | | | 11 | Numeric separators | icyfire | | 12 | Avoid using math/rand, use crypto/rand for keys instead | icyfire | -| 13 | | | +| 13 | Empty slice or, even better, NIL SLICE | icyfire | | 14 | | | | 15 | | | | 16 | | | diff --git a/src/013.md b/src/013.md new file mode 100644 index 0000000..15b13ee --- /dev/null +++ b/src/013.md @@ -0,0 +1,38 @@ +# Tip #13 使用空切片还是更好的NIL切片 + +> 原始链接:[Golang Tip #13: Empty slice or, even better, NIL SLICE.](https://twitter.com/func25/status/1754852685369524574) +> + +在Go里面使用切片的时候,有两个可以让你得到看起来像空切片的方法: + +### - 使用`var`关键字:`var t []int` + +这个方法声明了一个`int`类型的切片`t`,但并没有对它进行初始化。这时候这个切片被认为是`nil`的。 + +这意味着它并没有指向任何的底层数组。它的长度(`len`)和容量(`cap`)都是0。 + +### - 使用切片字面量: `t := []int{}` + +跟使用`var`声明的切片不一样,这个切片不是`nil`的。这个切片的指向了一个底层的数组,但这个数组并没有包含任何的元素。 + +### 所以,哪种方式更惯用呢? + +**1. nil切片没有分配任何的内存。** + +nil切片只是一个没有指向任何地方的指针,而空切片(`[]int{}`)则分配了很小的内存去指向一个空数组。 + +大多数情况下,这种差异是可以忽略的,但是对于有性能要求的应用来说,这个差异影响就比较明显了。 + +**2. Go社区更倾向于使用nil切片的方式**,因为这更加符合Go语言简单的哲学以及切片本身的零值。 + +**3. 当然,也有例外的情况。** + +例如,在使用JSON的时候,nil切片和空切片的表现是不一样的。 + +nil切片(`var t []int`)编码成JSON后的值是`null`,而空切片(`t := []int{}`)编码成JSON后的值是一个空的JSON数组(`[]`)。 + +**4.** 在设计代码的时候,你应该**同等对待非空切片、空切片和nil切片**。 + +如果你比较熟悉Go,你可能已经知道,对nil切片进行`for range`、`len`和`append`等操作是不会引起panic的。 + +![](./images/013/013_01.jpg) \ No newline at end of file diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 626f13b..ab4bf30 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -11,6 +11,7 @@ - [Tip #9 编译时接口检查](./009.md) - [Tip #11 数字分隔符](./011.md) - [Tip #12 使用 crypto/rand 生成密钥,避免使用 math/rand](./012.md) +- [Tip #13 使用空切片还是更好的NIL切片](./013.md) - [Tip #27 原地过滤](./027.md) - [Tip #44 有意地使用Must函数来停止程序](./044.md) - [Tip #47 表驱动测试,测试集和并行运行测试](./047.md) diff --git a/src/images/013/013_01.jpg b/src/images/013/013_01.jpg new file mode 100644 index 0000000..c2d7c80 Binary files /dev/null and b/src/images/013/013_01.jpg differ