Go中的切片Slice
切片概念
切片是一種資料結構, 是一種動態陣列, 按需自動改變大小, 可以方便的管理和使用資料集合
內部實現
- 切片基於陣列實現的, 切片的底層是陣列。
- 切片本身非常小, 是對陣列的抽象
- 因為切片基於陣列實現的, 所以底層的記憶體是連續分配的, 效率非常高
- 切片可以通過索引獲得資料, 可以迭代以及垃圾回收優化
- 切片是對陣列view的對映, 公用底層陣列, 改變切片就會改變底層陣列
切片宣告和初始化
宣告
-
make
方法, 單獨引數, 既指定長度也指定容量 -
// 長度和容量都是5 slice := make([]int, 5) 複製程式碼
-
make
方法, 兩個引數, 指定長度和容量 -
// 長度為5, 容量為10(容量對應底層陣列) slice := make([]int, 5, 10) 複製程式碼
- 切片的底層為陣列, 切片不指定值預設為零值
- 切片長度為5, 容量為10, 所以只能訪問5個值
- 剩下5個元素需要切片擴充後才能訪問
- 切片的容量必須 >= 切片的長度
-
使用
:=
建立切片// 此時切片的長度和容量都是5 slice:=[]int{1,2,3,4,5} 複製程式碼
-
使用
:=
建立部分切片// 此時切片的長度和容量都是5 slice:=[]int{4:1} 複製程式碼
-
陣列和切片的區別
//陣列 array:=[5]int{4:1} //切片 slice:=[]int{4:1} 複製程式碼
-
nil切片和空切片的區別,
他們的長度和容量都是0, 指向的底層陣列不同- nil切片指向底層陣列的指標為nil, 表示不存在的切片
- 空切片指向的底層陣列為指標為地址, 表示空切片集合
//nil切片 var nilSlice []int //空切片 slice:=[]int{} 複製程式碼
基於現有的陣列或者切片建立切片
- 使用[i:j]來建立新的切片, i為索引開始, j為索引結束, 半開半閉區間, 包含i, 不包含j
- i 和 j 都可省略, 省略後預設為 0 和 len(slice) – 1
- 對於陣列或者切片(容量為k)建立新的切片(slice[i:j])後的長度和容量為
長度為j - i
, 容量為k - i
- 系統內建方法長度為
len(slice)
, 容量為cap(slice)
使用第三個值來限制切片容量
- 建立了一個長度為
2 - 1 = 1
, 容量為3 - 1 = 2
- 第三個值不能超過原切片容量的最大值
slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:2:3]
複製程式碼
向切片追加值
- 通過
append
方法向切片追加值
slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:3]
newSlice=append(newSlice,10)
fmt.Println(newSlice)
fmt.Println(slice)
//Output
[2 3 10]
[1 2 3 10 5]
複製程式碼
- 通過
append
同時追加許多值
newSlice=append(newSlice,10,20,30)
複製程式碼
- 通過
...
和append
向切片中追加切片
slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:2:3]
newSlice = append(newSlice, slice...)
複製程式碼
- append函式會智慧的增長底層陣列的容量,目前的演算法是:容量小於1000個時,總是成倍的增長,一旦容量超過1000個,增長因子設為1.25,也就是說每次會增加25%的容量。
迭代切片
- 使用
for range
迭代切片
slice := []int{1, 2, 3, 4, 5}
for i,v:=range slice{
fmt.Printf("索引:%d,值:%d
",i,v)
}
複製程式碼
- 也可以使用
for
迭代切片
slice := []int{1, 2, 3, 4, 5}
for i := 0; i < len(slice); i++ {
fmt.Printf("值:%d
", slice[i])
}
複製程式碼
注意點
range
返回的是切片元素的複製, 不是元素的引用
在函式中傳遞切片
func main() {
slice := []int{1, 2, 3, 4, 5}
fmt.Printf("%p
", &slice)
modify(slice)
fmt.Println(slice)
}
func modify(slice []int) {
fmt.Printf("%p
", &slice)
slice[1] = 10
}
複製程式碼
注意點
- 傳遞複製切片時, 底層陣列不會被複制, 也不會收影響, 複製只是複製的切片本身, 不涉及底層陣列