1. 程式人生 > 實用技巧 >golang學習筆記----slice(22)

golang學習筆記----slice(22)

切片(slice)

切片(slice)是 Golang 中一種比較特殊的資料結構,這種資料結構更便於使用和管理資料集合。切片是圍繞動態陣列的概念構建的,可以按需自動增長和縮小。切片的動態增長是通過內建函式 append() 來實現的,這個函式可以快速且高效地增長切片,也可以通過對切片再次切割,縮小一個切片的大小。因為切片的底層也是在連續的記憶體塊中分配的,所以切片還能獲得索引、迭代以及為垃圾回收優化的好處。

切片的內部實現

切片是一個很小的物件,它對底層的陣列(內部是通過陣列儲存資料的)進行了抽象,並提供相關的操作方法。切片是一個有三個欄位的資料結構,這些資料結構包含 Golang 需要操作底層陣列的元資料:

這 3 個欄位分別是指向底層陣列的指標、切片訪問的元素的個數(即長度)和切片允許增長到的元素個數(即容量)。

切片的建立和初始化

在 Golang 中可以通過多種方式建立和初始化切片。是否提前知道切片所需的容量通常會決定如何建立切片

通過 make() 函式建立切片
使用 Golang 內建的 make() 函式建立切片,此時需要傳入一個引數來指定切片的長度:

// 建立一個整型切片
// 其長度和容量都是 5 個元素
slice := make([]int, 5)

此時只指定了切片的長度,那麼切片的容量和長度相等。也可以分別指定長度和容量:

// 建立一個整型切片
// 其長度為 3 個元素,容量為 5 個元素
slice := make([]int, 3, 5)

分別指定長度和容量時,建立的切片,底層陣列的長度是指定的容量,但是初始化後並不能
訪問所有的陣列元素。

注意,Golang 不允許建立容量小於長度的切片,當建立的切片容量小於長度時會在編譯時刻報錯:

// 建立一個整型切片
// 使其長度大於容量
myNum := make([]int, 5, 3)

編譯上面的程式碼,會收到下面的編譯錯誤:
len larger than cap in make([]int)

通過字面量建立切片
另一種常用的建立切片的方法是使用切片字面量,這種方法和建立陣列類似,只是不需要指定[]運算子裡的值。初始的長度和容量會基於初始化時提供的元素的個數確定:

// 建立字串切片
// 其長度和容量都是 3 個元素
myStr := []string{"Jack", "Mark", "Nick"}
// 建立一個整型切片
// 其長度和容量都是 4 個元素
myNum := []int{10, 20, 30, 40}

當使用切片字面量建立切片時,還可以設定初始長度和容量。要做的就是在初始化時給出所需的長度和容量作為索引。下面的語法展示瞭如何使用索引方式建立長度和容量都是100個元素的切片:

// 建立字串切片
// 使用空字串初始化第 100 個元素
myStr := []string{99: ""}

區分陣列的宣告和切片的宣告方式
當使用字面量來宣告切片時,其語法與使用字面量宣告陣列非常相似。二者的區別是:如果在 [] 運算子裡指定了一個值,那麼建立的就是陣列而不是切片。只有在 [] 中不指定值的時候,建立的才是切片。看下面的例子:

// 建立有 3 個元素的整型陣列
myArray := [3]int{10, 20, 30}
// 建立長度和容量都是 3 的整型切片
mySlice := []int{10, 20, 30}

nil 和空切片

有時,程式可能需要宣告一個值為 nil 的切片(也稱nil切片)。只要在宣告時不做任何初始化,就會建立一個 nil 切片

// 建立 nil 整型切片
var myNum []int