append函数的使用:
append可以向一个slice中追加一个元素、多个元素、新的切片
var x []int
x =append(x,1)// 追加一个元素
x =append(x,2,3,4)//追加多个元素
x =append(x,[]int{5,6,7}...)//追加一个新的切片
追加一个切片需要进行解包
append()的原理
- 如果原来slice capacity足够大的情况下,append()函数会创建一个新的slice,它与old slice共享底层内存创建原理:
newSlice = oldSlice[:1+len(x)]
用old slice给new slice进行赋值的方式进行创建,会共享内存。并返回这个new slice。> 因此为了保险,我们通常将append返回的内容赋值给原来的slice: x = appen(x,…) - 如果原来的slice没有足够的容量添加内容,则创建一个新的slice,这个slice是copy的old slice。不与old slice共享内存
实例:appendInt()
这个是只能追加一个元素的例子
追加之前,判断cap(x) 是否足够,
- 如果足够则创建的z 大小是 len(x) + 1
- 如果不够,则创建一个是原来两倍大的z
funcappendInt(x []int, y int)[]int{var z []int// 创建一个中间数组
zlen :=len(x)+1// 准备增加一个元素的位子// 判断 x 的cap是否足够容纳新的元素if zlen <=cap(x){// 容量足够,直接将x拷贝给y
z = x[:zlen]//如果容量足够要装一个z,比x大一个位子,因此要把x后面的空位也拷贝过去}else{// x 的容量不够 需要扩容
zcap := zlen // 如果xlen == 0if zcap <2*len(x){
zcap =2*len(x)//创建为原来的两倍}
z =make([]int, zlen, zcap)copy(z, x)}
z[len(x)]= y // 将y放在最后一个位子return z
}
测试:
funcmain(){var x, y []intfor i :=0; i <10; i++{
y =appendInt(x, i)
fmt.Printf("%d cap=%d\t%v\n", i,cap(y), y)
x = y
}}
每次容量的变化:
0cap=1[0]1cap=2[01]2cap=4[012]3cap=4[0123]4cap=8[01234]5cap=8[012345]6cap=8[0123456]7cap=8[01234567]8cap=16[012345678]9cap=16[0123456789]
拷贝:赋值 copy区别
=
赋值拷贝,会将原来slice的地址拷贝,新旧slice共享内存。
copy(new, old)
函数copy只会将slice内容进行拷贝。
var x, y []int
x =[]int{1,2,3,4}
fmt.Println(x, y)// [1 2 3 4] []
y = x
y[0]=0
fmt.Println("y 改后 : ", x, y)//[0 2 3 4] [0 2 3 4]
版权归原作者 死美子 所有, 如有侵权,请联系我们删除。