package main
import"fmt"funcmain(){
a :=[]int{0,1,2,3,4,5,6,7,8,9}
b := a[2:5]
c := b[2:6:7]
c =append(c,100)
c =append(c,200)
b[2]=20
fmt.Println(b)
fmt.Println(c)
fmt.Println(a)}
##输出
[2320][4567100200][0123205671009]
原因
1: b 从 a 索引2到索引5(左闭右开原则,元素为2,3,4),长度为3,容量默认到数组结尾,为8。
2: c从 b的索引2 到索引6(开区间,元素为4,5,6,7), 容量到索引7(开区间,真正到索引6),为5。
3: 接着,向 c 尾部追加一个元素 100,c容量刚好够,直接追加。
4: 不过,这会修改原始数组对应位置的元素。这一改动,数组和 b都可以看得到。
5: 再次向 c追加元素200,这时,c 的容量不够用,该扩容了。于是,c 将原来的元素复制新的位置,扩大自己的容量。并且为了应对未来可能的 append 带来的再一次扩容,c会在此次扩容的时候多留一些 buffer,将新的容量将扩大为原始容量的2倍,也就是10了。
6: 最后,修改 b索引为2位置的元素:b[2]=20。 由于只会影响原始数组的元素,而c已经扩容变成新数组,故不会影响c
考察点
切片复杂表达式
slice表达式分为简单表达式 a[low , high] 和扩展表达式 a[low : high : max]
扩展表达式中的max用于限制新生成切片的容量,新切片的容量为 max-low,表达式中low、high 和max的关系需要满足如下: o <= low <= high <= max <= cap(a)
切片底层数组共享
简单表达式生成的切片与原数组或者切片共享底层数组避免了拷贝元素,节约内存空间的同时,也会带来读写冲突的风险。新切片b( b := a[low : high] ) 不仅可以读写a[low] 到 a[high-1]之间的元素,而且在使用append(b,x)函数增加新元素x时,还可能会覆盖a[high]以及后面的元素