Golang 数组 & 切片 (十一)|Go主题月

1,085 阅读3分钟

虽然 Golang 中很少直接使用数组,但由于 切片 slice数组 arrays 的一种动态实现,所以讲解切片 slice 之前,很有必要先搞清楚 数组 arrays 如何实现。

数组 array

数组的声明

数组 arrays 就是一个 固定类型、固定长度 的序列。数组的语法如下:

var 变量名 [数组长度] 数组元素类型 // var a [2]int

数组中每个元素都能够通过 索引下标来访问,索引下标从 0 开始 到 数组长度 - 1,内置函数 len() 获得数组内元素个数(即:数组长度)。

数组初始化时每个元素的值默认为元素类型对应的零值,也可以声明直接赋值

var b [3]int = [3]int{1, 2, 3}

如果出事化时不清楚数组长度,可以是用 ... 表示数组长度根据初始化时元素个数决定

c := [...]int{1, 2, 3}

zenified-code.jpg

切片 slices

切片 slice 作为一种引用类型指向底层的数组,是对数组中某个 连续片段的引用。需要留意的是,终止索引下标值不包括在切片内

相对于数组的固定类型、固定长度,Slice 可以动态增长、变短,功能相对更灵活

切片的声明

从数组、切片的连续内存生成切片是常有操作,切片语法如下:

slice[开始位置 : 结束位置] // slice 被切片变量

注意:终止索引下标值不包括在切片内,举个例子:

zenified-code (1).jpg

切片的容量上限

创建切片 Slice 也会经常用到内建函数 make,语法如下:

func make([]Type, len, cap) []Type

需要注意的是第 3 个可选参数的容量上限。

  • 不指定 容量上限 cap 的话,默认会和原数组长度 len 相同。
  • 指定容量上限,切片后不能通过 slices[:cap(slices)] 访问原数组内容
  • cap 为切片 第一个元素原数组的索引值原数组长度的差值的绝对值
s := make([]int, 5),`切片 s` 长度为 5,容量上限 5。
s2 := s[1:3]

切片时 golang 会新建一个 切片 s2,底层的引用数据不动。s2 通过更改指针指向、长度、容量来进行切片。这也是切片性能非常高的原因。

一个切片不能越过容量上限 cap 进行操作,因为从指针的角度,这就是越界进行非法访问。

切片追加元素

Golang 的内建函数 append() 可以给切片动态追加元素, 当切片的容量上限不够容纳元素是,切片会自动进行扩容,此时切片长度会被改变。

切片扩容时,容量上限是有规律地按容量上限的 2 倍(1、2、4、8)进行扩充,并将之前的元素复制进去。下面测试了下:

zenified-code (2).jpg

如果要追加一个 slice 到另一个 slice 的话,这样:

zenified-code (3).jpg

切片复制

Golang 的内置函数 copy() 可以复制数组切片,使用语法如下:

copy(number1,number2) //拷贝 number2 的内容到 number1

需要注意的是:如果复制时两个切片容量上限并不一致,会按照容量上限较小的数组切片的容量上限进行复制。

zenified-code (4).jpg