关于 Slice 扩展的进一步思考
来源:3-3 切片的操作

ZYCGary
2023-08-01
在 Slice 的多次扩展中(s3,s4,s5),在超出 capacity 时在底层会创建一个更长的 array,那么这个创建新 array 的动作是在每次超出时都执行,还是只执行一次?超出 capacity 创建的 slice 是新的 array 的 view, 还是原始 array 的 view?
我测试了一下代码:
arr := [...]int{1, 2, 3, 4, 5, 6, 7, 8}
s1 := arr[2:6]
s2 := s1[3:5]
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println("s3, s4, s5 = ", s3, s4, s5)
fmt.Println("arr = ", arr)
结果是:
s3, s4, s5 = [6 7 10] [6 7 10 11] [6 7 10 11 12]
arr4 = [1 2 3 4 5 6 7 10]
在这段代码中,底层是创建了 1 个更长的 array 还是 2 个?s3,s4,s5 分别是哪个 array 的 view 呢?
1回答
-
weixin_慕莱坞8275679
2023-08-31
s1 := arr[2:6],s1截取的是原始arr,s1=[3,4,5,6]
s2 := s1[3:5]:s2截取s1,s1长度不足,最后一位扩展到底层arr的6下标处 s2=[6,7],此时,len(s2)=2, cap(s2)=3 (只剩底层的6,7,8了,前面的1,2,3,4,5已经被舍弃了,Slice只能向后扩展)s2=[6,7]
s3 := append(s2, 10):s2对应的是原始数组中的6,7,原始arr长度还足够,因此原始数组的最后一位直接改为10,此次没有创建新的arr; s3=[6,7,10]
s4 := append(s3, 11):s3对应原始数组的6,7,10,此时cap=3,继续追加,原始数组长度不足,此时创建一个新的数组,cap的扩容规则是2倍,因此对应的cap=6,将s3 copy进去,再追加一个11 s4=[6,7,10,11],此时len(s4)=4, cap=6
s5 := append(s4, 12):再次追加,上一步创建的cap=6,长度足够,直接追加一位,s5=[6,7,10,11,12],此时len(s5)=5, cap=6
所以,只有s4 := append(s3, 11)创建了更长的arr
00
相似问题
回答 1
回答 1
回答 1
回答 1
回答 1