先上一段代码,试想象一下打印arr的结果
a := arr[0:2]
a1 := append(a, 1)
a2 := append(a1, 2)
a3 := append(a1, 3)
log.Println(arr)
众所周知,slice的底层是一个struct,有arrPtr、len、cap三个属性,其中arrPtr指向一个数组,接下来让我们把arr打印出来看看
[0 0 1 3 ]
为什么是[0, 0, 1, 3],第4行append的2哪去了?
综合分析代码以及行为我们可以得出结论,当cap充足时,append会在slice对应的数组下标后面,直接添加元素,即使该位置是非零的,也会覆盖赋值。基于这个结论,我们再来看一下a1,a2,a3
arr := [4]int{0, 0}
a := arr[0:2]
a1 := append(a, 1)
a2 := append(a1, 2)
a3 := append(a1, 3)
log.Println(arr)//[0 0 1 3]
log.Println(a2)//[0 0 1 3]
log.Println(a3)//[0 0 1 3]
很显然,有些业务场景中,我们希望a2的值能独立出来,不要再依赖于a1,此时可以用一个copy
arr := [4]int{0, 0}
a := arr[0:2]
a1 := append(a, 1)
a2 := make([]int, len(a1))
copy(a2, a1)
a2 = append(a2, 2)
a3 := append(a1, 3)
log.Println(arr) //[0 0 1 3]
log.Println(a2) //[0 0 1 2]
log.Println(a3) //[0 0 1 3]
如果你希望有一个自由的slice,那么请为他准备一个独享的arr