golang中slice的擴容機制

閱讀此文檔默認已經掌握了slice的動態數組原理,若是沒有此認知,請閱讀https://i6448038.github.io/2018/08/11/array-and-slice-principle/ (本文也是在此連接基礎上擴展一些解釋說明)。

擴容

slice這種數據結構便於使用和管理數據集合,能夠理解爲是一種「動態數組」,slice也是圍繞動態數組的概念來構建的。既然是動態數組,那麼slice是如何擴容的呢?git

請記住如下兩條規則:github

  • 若是切片的容量小於1024個元素,那麼擴容的時候slice的cap就翻番,乘以2;一旦元素個數超過1024個元素,增加因子就變成1.25,即每次增長原來容量的四分之一。
  • 若是擴容以後,尚未觸及原數組的容量,那麼,切片中的指針指向的位置,就仍是原數組,若是擴容以後,超過了原數組的容量,那麼,Go就會開闢一塊新的內存,把原來的值拷貝過來,這種狀況絲絕不會影響到原數組。

知道了一下規則,請看下面程序,試問輸出結果:數組

1
2
3
4
5
6
7
8
9
10
import (
"fmt"
)
func main(){
array := [4]int{10, 20, 30, 40}
slice := array[0:2]
newSlice := append(append(append(slice, 50), 100), 150)
newSlice[1] += 1
fmt.Println(slice)
}

輸出:數據結構

1
[10 20]

上述程序中,因爲擴容了三次,超過了原始數組的容量,因此把原始數組拷貝過來,對新切片的修改並不影響原始數組的值。從而打印原始數組不影響原數組。app

 

若是:ui

1
2
3
4
5
6
7
8
9
10
import (
"fmt"
)
func main(){
array := [4]int{10, 20, 30, 40}
slice := array[0:2]
newSlice := append(append(slice, 50), 100)
newSlice[1] += 1
fmt.Println(slice)
}

 則輸出:spa

1
[10 21]

因爲擴容了兩次,沒有超過原始數組的容量,因此新切片指針仍是指向原始數組,對新切片的修改既對原始數組的修改。從而打印原始數組爲修改過的原數組。指針

相關文章
相關標籤/搜索