1. 程式人生 > >go array和slice的區別

go array和slice的區別

相同點:屬於集合類的型別,值都可以用來儲存某一種型別的值(或者說元素)

區別(最大的不同):陣列的長度固定,陣列是值型別(值型別有基本資料型別,結構體型別)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