1. 程式人生 > 其它 >Golang | 切片的定義和使用

Golang | 切片的定義和使用

切片

切片並不是陣列或者陣列指標,切片只是對陣列中連續片斷的引用,這個片斷可以是整個陣列,也可以是由起始索引和終止索引標識的陣列,所以切片是一個引用型別。

  // 切片的資料結構
  struct Slice{ 
    byte* array;
    uintgo len; 
    uintgo cap; 
  }
  • 切片是引用型別,但是自身是結構體,呼叫函式時是值傳遞。

  • len 屬性獲取長度,cap 屬性獲取容量

初始化

  func main() {
    s1 := []int{}
    var s2 []int
    s3 := make([]int,0)
    // s1[0] = 1  以下三種賦值都會報錯
    // s2[0] = 1  panic: runtime error: index out of range [0] with length 0
    // s3[0] = 1
    s1 = append(s1, 1)	// Slice 正確新增值的方式
    s2 = append(s2, 1)
    s3 = append(s3, 1)

    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(s3)
  }

一個切片在未初始化之前預設為 nil,長度為 0

或者通過陣列建立切片:

func main() {
	arrStr := [10]string{"a","b","c","d","e","f","h","i","j","k"}
	slice1 := arrStr[:]	// 包含陣列的全部元素
	slice2 := arrStr[3:] // 包含從第三個元素起一直到最後一個元素
	slice3 := arrStr[:8] // 包含第8個元素之前的所有元素

	fmt.Println(slice1)
	fmt.Println(slice2)
	fmt.Println(slice3)

	// 輸出:
	// [a b c d e f h i j k]
	// [d e f h i j k]
	// [a b c d e f h i]
}

通過這個方式建立陣列,實際上三個切片的索引還在底層陣列上,只是表現的形式不同

獲取切片的長度和容量:

	fmt.Println("slice2 的長度是:",len(slice2))
	fmt.Println("slice2 的容量是:",cap(slice2))

	// 輸出:
	// slice2 的長度是: 7
	// slice2 的容量是: 7

append

因為切片是一個引用型別,底層是一個數組,所以切片很容易就可以完成動態擴容。

  func main() {
    slice := make([]int,0)
    for i := 0; i < 10; i++ {
      slice = append(slice, i)
      fmt.Printf("長度:%d,容量:%d\n", len(slice), cap(slice))
    }
    // 輸出:
    // 長度:1,容量:1
    // 長度:2,容量:2

    // 長度:3,容量:4
    // 長度:4,容量:4

    // 長度:5,容量:8
    // 長度:6,容量:8
    // 長度:7,容量:8
    // 長度:8,容量:8

    // 長度:9,容量:16
    // 長度:10,容量:16
  }

切片後新增值使用 append 方法,直接在切片尾部新增值,並返回一個新的切片,之前的切片如果沒有使用,就會被GC回收。

根據上面的程式碼,可以得出:切片在每次長度=容量之後,切片的容量就會擴大兩倍

  func main() {
    slice := make([]int,0)
    for i := 0; i < 1030; i++ {
      slice = append(slice, i)
      if i > 1022{
        fmt.Printf("長度:%d,容量:%d\n", len(slice), cap(slice))
      }
    }
    // 輸出:
    // 長度:1024,容量:1024

    // 長度:1025,容量:1280
    // 長度:1026,容量:1280
    // 長度:1027,容量:1280
  }

根據這一次的程式碼,可以得出:切片的容量超過 1024 (1M)之後,每一次擴容都會增加前一次容量的 1/4

  • 切片的容量在 1024 之下時,每一次擴容容量翻倍
  • 切片的容量在 1024 之上時,每一次擴容容量增加前一次容量的 1/4


關注公眾號,隨時獲取最新資訊

細節決定成敗!
個人愚見,如有不對,懇請斧正!