iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Modern Web

就是個Go,我也可以啦!GOGO系列 第 10

2023鐵人賽Day 10 Go的資料結構-slice

  • 分享至 

  • xImage
  •  

Slice

當我在學習昨天的陣列時,我發現了一個很重要的限制,那就是無法改初始設定長度,故在擴充上就會有困難,接下來要介紹的是slice,相對於array,slice提供了更多的彈性

slice的原理

假設你在一張寫滿紙前面,這張紙就是陣列,他有固定長度,但是,你只對紙上某一部分有興趣,所以你拿了一張透明的塑膠片(這個塑膠片代表的就是slice),你把其中一塊罩住,因為其他部分你沒有興趣

  • 移動:有時候你感興趣的地方不同時,你可以直接移動塑膠片(改變起始位置及終點位置)
  • 原始陣列並未改變:由於你只是移動塑膠片,紙上的資料並不會因為你移動而改變
  • 你可以拿更多的塑膠片罩住同一張紙,也就代表我可以是不同slice,但指向同一個陣列

初始化

slice 是陣列的抽象,slice代表了一個變長的序列,其底層還是有陣列支持的,slice有三個屬性:指針,長度,容量

  • 長度:slice當前的長度
  • 容量: 切片的容量是從它的第一個元素開始數,到其底層數組元素末尾的個數
  1. 使用内建的 make 函数:

    s := make([]int, 5) 
    

    可以指定容量:

    s := make([]int, 5, 10) 
    
  2. 使用字面量:

    s := []int{1, 2, 3, 4, 5}  
    
  3. 通過現有的陣列或 slice 初始化:

    arr := [5]int{1, 2, 3, 4, 5}
    s1 := arr[1:4]   // slice 包括arr[1], arr[2], arr[3]
    s2 := arr[:2]    // slice 包括arr[0], arr[1]
    s3 := arr[3:]    // slice 包括arr[3], arr[4]
    
  4. 使用 nil slice:
    當一個 slice 被聲明沒有被分配到任何空間,它的值为 nil

    var s []int  // s == nil
    

切片的長度及容量

  • 只指定長度,容量被預設為和長度相同:
    如果你在使用 make 創建切片時,只指定了長度,那麼容量將被預設為和長度相同。

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        // 創建一個長度和容量都為5的整數切片
        numbers := make([]int, 5)
        fmt.Println("Len =", len(numbers), "Cap =", cap(numbers))
    }
    
    

    輸出為

    Len = 5 Cap = 5
    
  • 追加元素超過容量時的行為:
    當切片的元素數量超過其容量時,Go 會自動為切片分配一個新的、容量更大的陣列,並將原來的元素複製過去。

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        fruits := make([]string, 0, 3)
        fruits = append(fruits, "Apple", "Banana", "Cherry", "Date")
        fmt.Println("Len =", len(fruits), "Cap =", cap(fruits))
    }
    
    

    輸出為

    Len = 4 Cap = 6
    

    容量可能不會僅增加一,Go 可能會選擇增加更多的容量以確保後續的追加操作能更有效率


上一篇
2023鐵人賽 Day 9 Go的資料結構-陣列
下一篇
2023鐵人賽 Day 11 Go x 我們應該要把函數當成一等公民
系列文
就是個Go,我也可以啦!GOGO30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言