版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010918487/article/details/85490028
相同点:属于集合类的类型,值都可以用来存储某一种类型的值(或者说元素)
区别(最大的不同):数组的长度固定,数组是值类型(值类型有基本数据类型,结构体类型),slice的值长度可变,属于引用类型(引用类型:字典类型,通道类型,函数类型)
如果传递的是引用类型,那么就是“传引用”,如果传递的是值类型,那么就是“传值”
数组长度在声明的时候就必须给定,并且之后不会再改变。
slice类型的字面量中只有元素类型,没有长度。切片长度可以自动随着元素数量的增长而增长,但不会随着元素数量的减少而减少。
数组的容量=长度,不可改变。
一旦一个slice无法容纳更多的元素,go会扩容,但不会改变原来的切片,而是会生成一个容量更大的slice,然后把原有的元素和新元素一起copy到新的slice中。一般情况下,可简单认为新slice的容量是旧slice容量的2倍。
但是当原slice的长度>= 1024,go会以原容量的1.25倍作为新容量的基准,新容量基准会不断与1.25相乘,直到结果不小于原长度与要追加的元素数量之和。最终,新容量要比新长度要大 一些。
如果一次追加的元素过多,以至于使新长度比原容量的2倍还要大,那么新容量就会以新长度为基准。
一个slice的底层数组永远不会倍替换,虽然在扩容的时候,go一定会生成新的底层数组,但同时也生成了新的 slice。只是把新slice作为了新底层数组的窗口,而没有对原slice及其底层数组做任何改动。
在无需扩容的时候,append函数返回的是指向原底层数组的新slice。而在需要扩容的时候,append函数返回的是指向新底层数组的新的slice