golang-切片slice的基本介紹

机械心發表於2024-07-16

Go語言中的切片(slice)基礎

引子

在Go語言中,陣列的長度是固定的,且陣列長度屬於型別的一部分。這種特性限制了陣列的靈活性,無法動態擴容,對複雜情況難以適用。

切片的定義

切片(Slice)是一個擁有相同型別元素的可變長度的序列。它基於陣列型別進行了封裝,具有很大的靈活性,支援自動擴容。切片是引用型別,內部結構包含地址、長度和容量。通常用於快速操作一塊資料集合。

宣告切片的語法如下:

var name []T

其中name表示變數名,T表示切片中的元素型別。示例如下:

func main() {
	var a []string              //宣告一個字串切片
	var b = []int{}             //宣告一個整型切片並初始化
	var c = []bool{false, true} //宣告一個布林切片並初始化
	fmt.Println(a)              //[]
	fmt.Println(b)              //[]
	fmt.Println(c)              //[false true]
	fmt.Println(a == nil)       //true
	fmt.Println(b == nil)       //false
	fmt.Println(c == nil)       //false
}

切片的長度和容量

切片擁有自己的長度和容量。可以使用內建的len()函式求長度,使用內建的cap()函式求容量。

切片表示式

切片表示式用於從字串、陣列、指向陣列的指標或切片中構造子字串或切片。切片表示式有兩種形式:簡單形式和完整形式。

簡單切片表示式

切片基於陣列,可以透過切片表示式得到。切片表示式中的lowhigh表示一個索引範圍(左包含,右不包含),例如:

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	s := a[1:3]  
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", s, len(s), cap(s))
}

輸出結果:

s:[2 3] len(s):2 cap(s):4

可以省略切片表示式中的任何索引:

a[2:]  // 等同於 a[2:len(a)]
a[:3]  // 等同於 a[0:3]
a[:]   // 等同於 a[0:len(a)]

完整切片表示式

對於陣列、指向陣列的指標或切片,支援完整切片表示式:

a[low : high : max]

例如:

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	t := a[1:3:5]
	fmt.Printf("t:%v len(t):%v cap(t):%v\n", t, len(t), cap(t))
}

輸出結果:

t:[2 3] len(t):2 cap(t):4

使用make()函式構造切片

make()函式用於動態建立一個切片:

a := make([]int, 2, 10)
fmt.Println(a)      //[0 0]
fmt.Println(len(a)) //2
fmt.Println(cap(a)) //10

切片的本質

切片的本質是對底層陣列的封裝,包含底層陣列的指標、切片的長度(len)和切片的容量(cap)。

判斷切片是否為空

檢查切片是否為空,應該使用len(s) == 0而不是s == nil

切片不能直接比較

切片之間不能直接使用==運算子比較,只能與nil比較。

切片的賦值與複製

切片賦值操作是引用傳遞,兩個切片共享同一個底層陣列。使用copy()函式可以將一個切片的資料複製到另一個切片:

func main() {
	a := []int{1, 2, 3, 4, 5}
	c := make([]int, 5)
	copy(c, a)
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1 2 3 4 5]
}

切片遍歷

切片的遍歷方式與陣列相同,支援索引遍歷和for range遍歷。

使用append()函式為切片新增元素

append()函式可以為切片動態新增元素:

func main() {
	var s []int
	s = append(s, 1)        // [1]
	s = append(s, 2, 3, 4)  // [1 2 3 4]
	s2 := []int{5, 6, 7}  
	s = append(s, s2...)    // [1 2 3 4 5 6 7]
}

切片的擴容策略

切片的容量不足時,會按照一定的策略進行擴容。具體策略可以參考Go原始碼中的實現。

從切片中刪除元素

Go語言中沒有專用方法刪除切片元素,可以使用切片的特性:

a = append(a[:index], a[index+1:]...)

結論

切片是Go語言中一個非常靈活和強大的資料結構,理解切片的底層實現和操作方式對於編寫高效的Go程式碼非常重要。透過本文對切片的基本介紹和使用示例,相信讀者已經對Go語言中的切片有了一個較為全面的認識。

相關文章