通过数组或切片生成新的切片时,修改新切片可能会影响原有的数组或切片。直接上代码:
package main
import (
"fmt"
)
func main(){
// array是数组
array:=[...]int{1,2,3,4,5,6,7,8,9}
fmt.Printf("数组array的长度是%d,容量是%d\n", len(array), cap(array))
// slice是切片,定义时其实是指向数组array的引用,容量由原数组的最后一个元素位置决定
slice:=array[2:4]
fmt.Printf("切片slice的长度是%d,容量是%d\n", len(slice), cap(slice))
// slice切片追加一个元素,因为现有的容量(7)仍然能够满足追加后的空间需求(3),
// 所以切片不会扩容,对应的引用地址就不会变化
slice[0]=99
slice= append(slice, 123)
fmt.Printf("切片追加1个新元素后,原数组的值%+v\n",array)
fmt.Printf("切片追加1个新元素后,切片的值%+v,容量是%d\n",slice, cap(slice))
// slice切片追加一个切片(5个元素),因为现有的容量(7)将不能满足追加后的空间需求(8),
// 所以切片会扩容(*2倍),对应的引用地址将发生变化(不再指向原数组)
slice= append(slice,[]int{11,22,33,44,55}...)
fmt.Printf("切片追加新元素后,切片的值%+v,容量是%d\n",slice, cap(slice))
fmt.Printf("切片追加新元素后,原数组的值%+v\n",array)
}
结果:
数组array的长度是9,容量是9
切片slice的长度是2,容量是7
切片追加1个新元素后,原数组的值[1 2 99 4 123 6 7 8 9]
切片追加1个新元素后,切片的值[99 4 123],容量是7
切片追加新元素后,切片的值[99 4 123 11 22 33 44 55],容量是14
切片追加新元素后,原数组的值[1 2 99 4 123 6 7 8 9]
分析:
原数组一共有7个元素,数组的len和cap均为7;
定义的切片,len为2,cap为7(重点:7是根据原数组的元素计算而来),此时切片其实是引用的原数组地址,修改切片的第1个元素值为99,其实就是修改了原数组;
向切片追加1个新元素123,追加后的切片len将是3,此时切片现有的cap为7,是能够满足追加需求的,所以切片不会扩容,对应的也就不会重新分配新地址,追加的元素将直接覆盖原数组;
继续向切片追加1个切片(5个元素),追加后的切片len将是8,将超过现有cap(7),所以此次追加将导致切片扩容,重新分配新的空间。追加行为将在新的地址空间里发生,对原数组将不产生影响,追加后的切片cap将*2倍(2*7=14);
如果将原数组改成切片,效果是一样的。定义切片的代码将是:
array:=[]int{1,2,3,4,5,6,7,8,9}