Like Share Discussion Bookmark Smile

J.J. Huang   2025-02-16   Getting Started Golang 02.資料結構   瀏覽次數:次   DMCA.com Protection Status

Go | 初步了解「切片」型別

💬 簡介

切片(slice) 是一種非常重要的資料結構,它提供了比陣列更靈活的方式來儲存資料。與陣列不同,切片的大小是動態的,可以根據需求增長或縮小。切片不僅能夠有效地處理大資料集,還能與陣列進行簡單的交互操作。

本文將介紹切片的基本概念、如何創建和使用切片,並展示一些常見的範例。

圖片來源:Gophers(地鼠造型的原創者為 Renee French)


✨ 切片的基本概念

切片 是基於陣列的一個動態資料結構,它的內部實際上是一個指向底層陣列的結構,並且可以隨著元素的增減而自動調整大小。切片是 Go 中處理資料集合的主要工具之一。

1️⃣ 切片的宣告與初始化

與陣列相比,切片不需要事先確定大小,並且可以根據需要擴展。你可以使用內建的 make 函式來創建切片,或者直接通過初始化來創建。

  • 範例:切片的創建與初始化

    1
    2
    var numbers []int
    fmt.Println(numbers) // 輸出: []

    📝 在這個範例中,我們創建了一個空的切片,它的初始長度為 0,容量也是 0。

  • 範例:範例:使用 make 函式創建切片

    1
    2
    numbers := make([]int, 5)
    fmt.Println(numbers) // 輸出: [0 0 0 0 0]

    📝 這樣,我們創建了一個長度為 5、初始值為 0 的切片。

  • 範例:直接初始化切片

    1
    2
    numbers := []int{1, 2, 3, 4, 5}
    fmt.Println(numbers) // 輸出: [1 2 3 4 5]

    📝 使用這樣的初始化方式,可以在創建切片的同時指定其內容。

2️⃣ 切片的長度與容量

切片有兩個重要的屬性:長度和容量。len() 函式用來獲取切片的長度,而 cap() 函式則用來獲取切片的容量。

  • 範例:範例:切片的長度與容量
    1
    2
    fmt.Println(len(numbers)) // 輸出: 5
    fmt.Println(cap(numbers)) // 輸出: 5

    📝 在這個範例中,len() 返回切片的元素個數,cap() 返回底層陣列的容量。


🛠️ 範例:基本切片操作

1️⃣ 添加元素到切片

切片的大小是動態可變的,使用 append() 函式可以向切片中添加元素。

  • 範例:範例:添加元素
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package 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
    10
    package 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
    15
    package 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
    12
    package 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