go语言读书笔记-action系列(切片)

go语言中的切片,感觉就像动态数组一样,自由的增删元素,更改大小。相比数组的固定大小,在编程中提供了不小的方便。不同于java中数据集合的各种抽象(map,set,list),以及三大基础结构底下的各个容器,go的集合表示很简单,就只有数组、切片、映射(当然比起php一切皆array逊色很多,但是我go快啊),感觉go应该是总结了各个语言的特性,总结除了这三种最具有普适性的结构,从而可以适应各种需要。

切片的内部实现

image_1d4rgl7v3tf2110v19hd80t1q1dp.png-66.2kB
在go中,切片可以看作对底层数组所做的抽象,切片的数据包含三个字段:

  • 指向数组的指针
  • 切片访问元素的个数
  • 允许增长到的元素个数(就是切片的容量,占用的内存空间)

通过这种结构,明显可以发现在使用切片时需要十分小心,因为其共享底层数组,可能一不小心就会干扰到其它切片的元素。
但是这种结构也使得切片在函数间传递时不用像数组那样传递过大的数据量,无论多大的切片都只有24个字节(指针8个,元素个数8个,容量8个),极大的提升了效率。

append

使用append可以向切片中增加元素:

func append(slice []Type, elems …Type) []Type

append 在切片容量足够时,直接将元素插入底层数组并更新切片访问元素的个数。切片的容量在不足够时append会自动生成新的切片增加容量,每次增加的容量是原来的两倍。但是当元素个数超过1000时,append容量的增长因子会被设为1.25。

创建切片的三个索引

在创建切片时,原来还可以使用第三个索引,第三个索引是用来控制切片的容量。

  • 为什么需要限制切片的容量?

因为切片存在多个切片共用一个数组的情况,有时可能会由于误操作影响到其他切片,所以设置了容量的情况下,在添加元素时就可以强制使得append为了增加容量申请新的底层数组,从而保证即使误操作也不会影响到其它切片。