数组和切片的区别
slice 的底层数据是数组,slice 是对数组的封装,它描述一个数组的片段。两者都可以通过下标来访问单个元素。
两者不一样
举例说明
go和js语言表达不太一样,很少说数组这一个概念吗,更多时候对数组的表达会说切片,因为数据长度是其类型的一部分,比如[3]int和[4]int就是不同类型。
但是切片就很灵活,可以动态扩容(这个是数组做不到的),其根本原因是结构定义不一样
1 | type slice struct { |
看个例子,例子来自雨痕大佬《Go学习笔记》第四版,P43页
1 | package main |
s1
从 slice
索引2(闭区间)到索引5(开区间,元素真正取到索引4),长度为3,容量默认到数组结尾,为8。 s2
从 s1
的索引2(闭区间)到索引6(开区间,元素真正取到索引5),容量到索引7(开区间,真正到索引6),为5。
接着,向 s2
尾部追加一个元素 100:
s2
容量刚好够,直接追加。不过,这会修改原始数组对应位置的元素。这一改动,数组和 s1
都可以看得到。
再次向 s2
追加元素200:
这时,s2
的容量不够用,该扩容了。于是,s2
另起炉灶,将原来的元素复制新的位置,扩大自己的容量。并且为了应对未来可能的 append
带来的再一次扩容,s2
会在此次扩容的时候多留一些 buffer
,将新的容量将扩大为原始容量的2倍,也就是10了。
最后,修改 s1
索引为2位置的元素:
这次只会影响原始数组相应位置的元素。它影响不到 s2
了,人家已经远走高飞了。
再提一点,打印 s1
的时候,只会打印出 s1
长度以内的元素。所以,只会打印出3个元素,虽然它的底层数组不止3个元素。