Golang slice append
Golang 的数组是长度固定的, 一旦声明其长度就无法修改.
切片为数组操作提供了一定的灵活性.
切片本质上是对数组的封装, 把数组的一部分暴露出来. 切片是可变的.
切片包含长度和容量的概念, 长度内的空间是可以直接赋值操作的; 长度以外, 容量以内的, 不能直接赋值, 但可以通过 append 方法来使用容量.
package main
import "fmt"
func main() {
arr := [10]int{1, 2, 3, 4, 5, 6, 7, 9, 10}
slice := arr[2:5:6]
slice = append(slice, 100)
slice = append(slice, 101)
slice = append(slice, 102)
fmt.Println(arr, slice)
}
对于一个长度为 l 的数组 arr, slice := arr[i:j:k]
表示从 arr 中切片出 slice, 长度从i到j, 包括i不包括j; 容量从i到k, 包括i不包括k.
k 是可选的, k 默认跟 l 相等, 即容量直到数组的结尾(包含最后一个元素).
例如: arr 是一个长度为 10 的数组, 它的长度是不可修改的. slice := arr[2:5:6]
, slice 从 arr 中切片出来, 新的切片包含从第 2 个元素到第 5 个元素, 长度为 3, 容量为从第 2 个元素到第 6 个元素, 容量为 4 .
切片的 append 方法, 把新元素追加到长度之后的容量位置. slice := arr[2:5:6]
本身是 [3, 4, 5]
, 长度为3, 容量为 4, append 100 后, 把剩余的一个容量占满, 也就是 [3, 4, 5, 100]
.
特别注意, 这里的 100 占用的是原底层数组的空间, 这个修改会影响到 arr, arr 的 6 被修改为了 100.
当 append 101 的时候, 容量已经满了, 这时候切片会自己去申请新的空间来存放 101. arr 的 7 不会被修改.
当切片的容量在 1000 以下时, 切片只能扩展是容量翻倍; 当切片的容量在 1000 以上的时候, 新容量是原来的 1.25 倍.
append 102 被安排在新的已经扩展的容量内.
所以, 上面 DEMO 的 outputs:
[1 2 3 100 5] [3 100 101 102]