1. 程式人生 > 實用技巧 >Go的切片:長度和容量

Go的切片:長度和容量

一、切片的宣告

切片可以看成是陣列的引用。在 Go 中,每個陣列的大小是固定的,不能隨意改變大小,切片可以為陣列提供動態增長和縮小的需求,但其本身並不儲存任何資料。

/*
 * 這是一個數組的宣告
 */
var a [5]int //只指定長度,元素初始化為預設值0
var a [5]int{1,2,3,4,5}

/* 
 * 這是一個切片的宣告:即宣告一個沒有長度的陣列
 */
// 陣列未建立
// 方法1:直接初始化
var s []int //宣告一個長度和容量為 0 的 nil 切片
var s []int{1,2,3,4,5} // 同時建立一個長度為5的陣列
// 方法2:用make()函式來建立切片:var 變數名 = make([]變數型別,長度,容量)
var s = make([]int, 0, 5) // 陣列已建立 // 切分陣列:var 變數名 []變數型別 = arr[low, high],low和high為陣列的索引。 var arr = [5]int{1,2,3,4,5} var slice []int = arr[1:4] // [2,3,4]

二、切片的長度和容量

切片的長度是它所包含的元素個數。
切片的容量是從它的第一個元素到其底層陣列元素末尾的個數。
切片 s 的長度和容量可通過表示式len(s)cap(s)來獲取。

s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} // [0 1 2 3 4 5 6 7 8 9] len=10,cap=10
s1 := s[0:5] // [0 1 2 3 4] len=5,cap=10 s2 := s[5:] // [5 6 7 8 9] len=5,cap=5

三、切片追加元素後長度和容量的變化

1.append 函式

Go 提供了內建的 append 函式,為切片追加新的元素。

func append(s []T, vs ...T) []T

append 的結果是一個包含原切片所有元素加上新新增元素的切片。

下面分兩種情況描述了向切片追加新元素後切片長度和容量的變化。
Example 1:

package main

import "fmt"

func main() {
    arr := [5
]int{1,2,3,4,5} // [1 2 3 4 5] fmt.Println(arr) s1 := arr[0:3] // [1 2 3] printSlice(s1) s1 = append(s1, 6) printSlice(s1) fmt.Println(arr) } func printSlice(s []int) { fmt.Printf("len=%d cap=%d %p %v\n", len(s), cap(s), s, s) }

執行結果如下:

[1 2 3 4 5]
len=3 cap=5 0xc000082030 [1 2 3]
len=4 cap=5 0xc000082030 [1 2 3 6]
[1 2 3 6 5]

可以看到切片在追加元素後,其容量和指標地址沒有變化,但底層陣列發生了變化,下標 3 對應的 4 變成了 6。

Example 2:

package main

import "fmt"

func main() {
    arr := [5]int{1,2,3,4} // [1 2 3 4 0]
    fmt.Println(arr)
    
    s2 := arr[2:] // [3 4 0]
    printSlice(s2)
    s2 = append(s2, 5)
    printSlice(s2)
    fmt.Println(arr)
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %p %v\n", len(s), cap(s), s, s)
}

執行結果如下:

[1 2 3 4 0]
len=3 cap=3 0xc00001c130 [3 4 0]
len=4 cap=6 0xc00001c180 [3 4 0 5]
[1 2 3 4 0]