Go | 初步了解「切片」型別
💬 簡介
切片(slice) 是一種非常重要的資料結構,它提供了比陣列更靈活的方式來儲存資料。與陣列不同,切片的大小是動態的,可以根據需求增長或縮小。切片不僅能夠有效地處理大資料集,還能與陣列進行簡單的交互操作。
本文將介紹切片的基本概念、如何創建和使用切片,並展示一些常見的範例。
圖片來源:Gophers(地鼠造型的原創者為 Renee French)
✨ 切片的基本概念
切片 是基於陣列的一個動態資料結構,它的內部實際上是一個指向底層陣列的結構,並且可以隨著元素的增減而自動調整大小。切片是 Go 中處理資料集合的主要工具之一。
1️⃣ 切片的宣告與初始化
與陣列相比,切片不需要事先確定大小,並且可以根據需要擴展。你可以使用內建的 make
函式來創建切片,或者直接通過初始化來創建。
範例:切片的創建與初始化
1
2var numbers []int
fmt.Println(numbers) // 輸出: []📝 在這個範例中,我們創建了一個空的切片,它的初始長度為 0,容量也是 0。
範例:範例:使用 make 函式創建切片
1
2numbers := make([]int, 5)
fmt.Println(numbers) // 輸出: [0 0 0 0 0]📝 這樣,我們創建了一個長度為 5、初始值為 0 的切片。
範例:直接初始化切片
1
2numbers := []int{1, 2, 3, 4, 5}
fmt.Println(numbers) // 輸出: [1 2 3 4 5]📝 使用這樣的初始化方式,可以在創建切片的同時指定其內容。
2️⃣ 切片的長度與容量
切片有兩個重要的屬性:長度和容量。len()
函式用來獲取切片的長度,而 cap()
函式則用來獲取切片的容量。
- 範例:範例:切片的長度與容量
1
2fmt.Println(len(numbers)) // 輸出: 5
fmt.Println(cap(numbers)) // 輸出: 5📝 在這個範例中,
len()
返回切片的元素個數,cap()
返回底層陣列的容量。
🛠️ 範例:基本切片操作
1️⃣ 添加元素到切片
切片的大小是動態可變的,使用 append()
函式可以向切片中添加元素。
- 範例:範例:添加元素
1
2
3
4
5
6
7
8
9
10
11package main
import "fmt"
func main() {
var fruits []string
fruits = append(fruits, "Apple")
fruits = append(fruits, "Banana", "Cherry")
fmt.Println(fruits) // 輸出: [Apple Banana Cherry]
}📝 這個範例展示了如何使用 append() 向切片中添加一個或多個元素。
2️⃣ 切片的切割操作
切片也支持切割操作,可以從一個切片中創建一個新的切片,這樣新的切片共享原來切片的底層陣列。
- 範例:範例:切割切片
1
2
3
4
5
6
7
8
9
10package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
slice1 := numbers[1:4] // 包含索引 1 到 3 的元素
fmt.Println(slice1) // 輸出: [2 3 4]
}📝 這個範例展示了如何從原始切片中提取一個子切片。
3️⃣ 複製切片
使用內建的 copy()
函式,可以將一個切片的內容複製到另一個切片中。注意,copy() 是按元素複製,而不是按引用複製。
- 範例:範例:複製切片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package main
import "fmt"
func main() {
source := []int{1, 2, 3, 4, 5}
var destination []int
// 複製 source 切片的內容到 destination
destination = make([]int, len(source))
copy(destination, source)
fmt.Println("Source:", source) // 輸出: Source: [1 2 3 4 5]
fmt.Println("Destination:", destination) // 輸出: Destination: [1 2 3 4 5]
}📝 在這個範例中,
copy()
函式將source
切片的內容複製到destination
切片中,兩個切片是獨立的。
4️⃣ 刪除切片元素
在 Go 中,沒有內建的刪除函式,但我們可以通過使用切片切割操作來刪除元素。刪除某個元素實際上是創建一個新的切片,將想保留的部分和想刪除的部分進行拼接。
- 範例:範例:刪除切片中的元素
1
2
3
4
5
6
7
8
9
10
11
12package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
// 刪除索引為 2 的元素 (即 3)
numbers = append(numbers[:2], numbers[3:]...)
fmt.Println(numbers) // 輸出: [1 2 4 5]
}📝 在這個範例中,我們通過切片操作來刪除
numbers
切片中索引為2
的元素,結果是切片[1 2 4 5]
。
🚀 切片的優化與限制
🔧 切片的容量增長
當使用 append()
函式向切片中添加元素時,如果切片的容量不足以容納新元素,Go 會自動擴展切片的容量。這個擴展是指在切片的容量已滿時,Go 會創建一個新的底層陣列,並將舊切片的元素複製過去。
🧨 固定大小的陣列 vs 動態大小的切片
- 陣列:固定大小,效率較高,適用於需要確定數量的元素。
- 切片:動態大小,彈性較大,適用於元素數量不確定的情境。
🎯總結
切片是 Go 語言中非常強大且靈活的資料結構,它可以動態擴展大小,並且具有比陣列更多的靈活性。了解切片的基本操作和限制將幫助你在 Go 語言中更高效地處理資料集合。
最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。
註:以上參考了
Go
Go-Slice types