append 函数

func append(slice []Type, elems ...Type) []Type
将元素添加至切片中,如果超出了容量,将会返回一个容量二倍与当前切片的切片

本身我们看不见append的代码,所以我就随便模拟了一下

func addInt(x []int, y int) []int{
	var z []int
	zlen := len(x) + 1
	if zlen	<= cap(x) {
		//判断 zlen 是否超过了x的cap
		// 没有超过 直接赋值
		z = x[:zlen]
	} else { // 如果zlen 超过了x的cap
		zcap := zlen // 将zlen赋值非zcap
		// 这儿相当于 将x的cap 扩容了一倍, 和原本的append函数一样
		if zcap	<= 2 * len(x) {
			zcap = 2*len(x)
		}
	// 初始化新切片,将原来的值复制过去
		z = make([]int,zlen,zcap)
		copy(z,x)
	}
	// 最后一个元素为y 返回z
	z[len(x)] = y

	return z
}

每次调用addInt函数,必须先检测slice底层数组是否有足够的容量来保存新添加的元素。如果有足够空间的话,直接扩展slice(依然在原有的底层数组之上),将新添加的y元素复制到新扩展的空间,并返回slice。因此,输入的x和输出的z共享相同的底层数组。

如果没有足够的增长空间的话,appendInt函数则会先分配一个足够大的slice用于保存新的结果,先将输入的x复制到新的空间,然后添加y元素。结果z和输入的x引用的将是不同的底层数组。