1. 程式人生 > >Go語言中切片的使用

Go語言中切片的使用

1 概述

其中切片是基於資料中連續片段的引用,是一個引用型別。與陣列不同的是,切片的長度可以在執行時修改。使用上可以將切片看作是長度可變的陣列。即使超過了底層陣列的最大長度,也可以繼續擴容。

圖例為: slice示意

切片的實現是由一個底層陣列以及其上面的動態位置,尺寸來實現。由內部由指向起始元素的指標、元素數量length和容量capacity組成。其中:

  • 指標ptr,用於指向切片在底層陣列的起始位置。
  • 尺寸len,用於記錄切片內元素數量。
  • 容量cap,當前切片最大容量,也就是底層陣列的容量。可以動態分配。

當使用不定數量引數時,函式得到的引數也是切片型別。

切片為引用型別,因此切片的預設初始值為nil。

2 建立切片

語法整理如下:

  • []type,切片型別
  • []type{v1, v2, v3},定義時指定初始值
  • make([]type, len),make開闢記憶體空間,指定型別和長度
  • make([]type, len, cap),make開闢切片記憶體空間,指定型別,長度和容量
  • arr[start?max],由陣列或切片建立 其中: 開始索引start,表示從哪個元素開始。 結束索引end,表示到哪個索引終止,不包括該索引元素。 最大索引max,用來確定容量,容量=最大索引-開始索引。預設情況下,最大索引的值為len()。

3 for-range 遍歷

for i, v := range sli {
  fmt.Println(i, v)
}

4 append() 擴容

func append(s []T, x …T) []T 使用 buildin 函式 append() 可以向切片中新增新元素。新增時存在兩種情況:

  • 切片容量充足,在原切片基礎上追加。
  • 切片容量不足,會分配新的切片空間來保證已有切片元素和新增元素的儲存。
s1 := make([]int, 3, 5)
s2 := append(s1, 1, 2)
s2[1] = 42
fmt.Println(s1)
fmt.Println(s2)
// [0 42 0] 修改s2,s1也會更改
// [0 42 0 1 2]

s3 := make([]int, 3, 5)
s4 := append(s1, 1, 2, 3, 4, 5)
s4[1] = 42
fmt.Println(s3)
fmt.Println(s4)
// [0 0 0] 修改s4,s3不會更改,因為容量不足,開闢了新空間
// [0 42 0 1 2 3 4 5]

可以將一個切片到另一個切片後,需要使用 切片… 來實現:

append(slice1, slice2…)

5 copy() 拷貝切片

由於預設是地址傳遞賦值方式,當需要得到一個新的拷貝時,需要使用函式copy()來實現。 copy(新切片,舊切片),利用舊切片複製一份新切片。

s3 := []int{10, 20, 30}
var s4 = make([]int, 3)
copy(s4, s3)

6 常用操作

配合 make,append,copy 可以完成切片的常用操作。

通過索引 i 刪除切片中某個元素

s2 := append(s1[:i], s1[i+1:]...)

刪除索引 i-j 的元素

s2 := append(append([]int{}, s1[:i]...), s1[j:]...)

在索引 i 的位置插入元素

s2 := append(s1[:i], append([]int{v}, s1[i:]...)...)

在 s1 索引 i 的位置插入切片 s2 的所有元素

s1 = append(s1[:i], append(s2, s1[i:]...)...)

棧操作模擬

// 棧模擬(只在一端的頭,新增或者刪除元素)
var s1 = []int{6, 7, 8, 9, 10, 11}
// 操作末尾
// 入棧
s1 = append(s1, 12)
fmt.Println(s1)
// 出棧
v := s1[len(s1)-1]
s1 = s1[:len(s1)-1]
fmt.Println(v, s1)

// 操作頭部
// 入棧
s1 = append([]int{5}, s1...)
fmt.Println(s1)
// 出棧
v := s1[0]
s1 = s1[1:]
fmt.Println(v, s1)

佇列操作模擬

// 模擬佇列
// 頭進尾出
var s1 = []int{6, 7, 8, 9, 10, 11}
s1 = append([]int{5}, s1...)
v := s1[len(s1)-1]
s1 = s1[:len(s1)-1]

// 尾進頭出
var s1 = []int{6, 7, 8, 9, 10, 11}
s1 = append(s1, 12)
v := s1[0]
s1 = s1[1:]

完! 原文出自:小韓說課 微信關注:小韓說課 小韓說課