Go 切片 slice - Go 學習記錄

Ali發表於2019-03-04

slice 切片型別基本概念

  • slice 總是指向一個底層的 array,slice 的宣告也可以像 array 一樣,只是不需要定義長度
  • slice 並不是真正意義上的動態陣列,而是一個引用型別。
  • slice 是引用型別,所以當改變其中元素的值時,其他的所有引用都會改變該值。
  • slice 可以從一個陣列或一個已經存在的slice中再次宣告。slice 通過 array[i:j] 來獲取,其中 i 是陣列的開始位置,j 是結束位置,但不包含 array[j],它的長度是 j - i。
  • 宣告 slice 時,方括號內沒有任何字元,

slice 切片型別基本使用

  • 基本宣告語法
    var sliceType []type
    // 宣告一個含有 int 型別元素的 slice
    var aSlice =  []int{1,2,3,4,5}
    fmt.Print(aSlice)     // 全部輸出 [1,2,3,4,5]
    fmt.Print(aSlice[0])  // 輸出 1
  • make 指定 slice 完整的屬性
// 第一個引數是型別,
// 第二個引數包含多少個元素,
// 第三個引數是 slice 的初始容量(如果不設定初始化容量,預設的記憶體長度為你的值的長度)
    s1 := make([]int,3)
    fmt.Print(len(s1),cap(s1)) // 3,3
    s2 := make([]int,3,10)
    fmt.Print(len(s2),cap(s2)) // 3,10
  • 練習

    // 宣告一個含有 8 int 型別元素的 陣列
    var array = [8]int{1,3,4,6,7,8,9,10}
    // 宣告三個含有 int 型別的 slice
    var bSlice,cSlice,dSlice []int
    dSlice = array[:2]  // 等價於 aSlice = array[0:3] aSlice 包含元素0和1不包含2 結果為:1,3
    bSlice = array[3:]  // 等價於 aSlice = array[3:5] aSlice 結果為:6,7,8,9,10
    cSlice = array[:]   // 等價於 aSlice = array[0:8] aSlice 包含元素所有的array 的元素
    // slice 上面的一些簡便的操作解釋
    /**
     * slice 預設是從0開始的。arr[:n] 和 arr[0:n] 是一個意思
     * slice 的第二個序列預設是陣列的長度, arr[n:] 等價於 arr[n:len(arr)]
     * 如果從一個陣列裡面直接獲取 slice 可以這樣子 arr[:] ,因為預設第一個序列是 0 第二個是陣列的長度,即等價於 arr[0:len(arr)]
     */
    
    // 從 slice 中獲取 slice
    var eSlice []int
    eSlice = cSlice[1:3] // 包含了 cSlice[1],cSlice[2] 也就是 3,4
    eSlice = cSlice[0:3] // 包含了 cSlice[0],cSlice[1],cSlice[2] 也就是1,3,4
    // 注:讀取 slice 時索引以被 slice 的切片為準,索引不可以超過被 slice 切片的容量cap() 的值
    
    // 宣告一個含有10個元素元素型別為byte的陣列
    var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
    
    // 宣告兩個含有byte的slice
    var aa, bb []byte
    
    // a指向陣列的第3個元素開始,併到第五個元素結束,
    aa = ar[2:5]
    // 現在 aa 含有的元素: ar[2]、ar[3]和ar[4]
    fmt.Print(string(aa)) // c d e
    // bb 是陣列 ar 的另一個 slice
    fmt.Print(len(aa),cap(aa)) // 3  8 長度為3,容量為 8
    bb = aa[0:5] // 對 aa 的 bb 可以在 cap 範圍內擴充套件,此時 bb 包含:c,d,e,f,g
    fmt.Print(string(bb)) // c,d,e,f,g

slice 中可以使用的內建的函式

  • len 獲取 slice的最大長度
  • cap 獲取 slice 的最大容量
  • copy 函式 copy 從源 slice 的 src 中複製元素到目標 dst ,並且返回複製的元素的個數
  • append 像 slice 裡面追加一個或者多個元素,然後返回一個和 slice 一樣型別的 slice
    注意: append 函式會改變slice所引用的陣列的內容,從而影響到引用同一陣列的其他slice ,但當slice中沒有剩餘空間 (即( cap - len) = 0 )時,此時將動態分配新的陣列空間,返回的 slice 陣列指標將指向這個空間。而原陣列的內容將保持不變; 其他引用此陣列的 slice 則不受影響。

    如想看記錄同步的程式碼移步 GitHub 地址。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

高永立

相關文章