閱讀此文檔默認已經掌握了slice的動態數組原理,如果沒有此認知,請閱讀https://i6448038.github.io/2018/08/11/array-and-slice-principle/ (本文也是在此鏈接基礎上擴展一些解釋說明)。
擴容
slice這種數據結構便於使用和管理數據集合,可以理解為是一種“動態數組”,slice
也是圍繞動態數組的概念來構建的。既然是動態數組,那么slice是如何擴容的呢?
請記住以下兩條規則:
- 如果切片的容量小於1024個元素,那么擴容的時候slice的cap就翻番,乘以2;一旦元素個數超過1024個元素,增長因子就變成1.25,即每次增加原來容量的四分之一。
- 如果擴容之后,還沒有觸及原數組的容量,那么,切片中的指針指向的位置,就還是原數組,如果擴容之后,超過了原數組的容量,那么,Go就會開辟一塊新的內存,把原來的值拷貝過來,這種情況絲毫不會影響到原數組。
知道了一下規則,請看下面程序,試問輸出結果:
1 |
import ( |
輸出:
1 |
[10 20] |
上述程序中,由於擴容了三次,超過了原始數組的容量,所以把原始數組拷貝過來,對新切片的修改並不影響原始數組的值。從而打印原始數組不影響原數組。
如果:
1 |
import ( |
則輸出:
1 |
[10 21] |
由於擴容了兩次,沒有超過原始數組的容量,所以新切片指針還是指向原始數組,對新切片的修改既對原始數組的修改。從而打印原始數組為修改過的原數組。