Go的切片 長度和容量

2022-07-11 11:24:10 字數 3208 閱讀 3993

一、切片的宣告

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

/*

* 這是乙個陣列的宣告

*/var a [5]int //只指定長度,元素初始化為預設值0

var a [5]int

/* * 這是乙個切片的宣告:即宣告乙個沒有長度的陣列

*/// 陣列未建立

// 方法1:直接初始化

var s int //宣告乙個長度和容量為 0 的 nil 切片

var s int // 同時建立乙個長度為5的陣列

// 方法2:用make()函式來建立切片:var 變數名 = make(變數型別,長度,容量)

var s = make(int, 0, 5)

// 陣列已建立

// 切分陣列:var 變數名 變數型別 = arr[low, high],low和high為陣列的索引。

var arr = [5]int

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] 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

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

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

example 1:

package main

import "fmt"

func main() // [1 2 3 4 5]

fmt.println(arr)

s1 := arr[0:3] // [1 2 3]

printslice(s1)

printslice(s1)

fmt.println(arr)

}func printslice(s int)

執行結果如下:
[123

45]len=3 cap=5

0xc000082030 [123

]len=4 cap=5

0xc000082030 [123

6][1

2365]

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

example 2:

package main

import "fmt"

func main() // [1 2 3 4 0]

fmt.println(arr)

s2 := arr[2:] // [3 4 0]

printslice(s2)

printslice(s2)

fmt.println(arr)

}func printslice(s int)

執行結果如下:

[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]

而這個切片在追加元素後,其容量和指標位址發生了變化,但底層陣列未變。

當切片的底層陣列不足以容納所有給定值時,它就會分配乙個更大的陣列。返回的切片會指向這個新分配的陣列。

2.切片的源**學習

go 中切片的資料結構可以在原始碼下的src/runtime/slice.go檢視。

// go 1.3.16 src/runtime/slice.go:13

type slice struct

可以看到,切片作為陣列的引用,有三個屬性字段:長度、容量和指向陣列的指標。

向 slice 追加元素的時候,若容量不夠,會呼叫 growslice 函式,

// go 1.3.16 src/runtime/slice.go:76

func growslice(et *_type, old slice, cap int) slice else else

// set newcap to the requested cap when

// the newcap calculation overflowed.

if newcap <= 0 }}

// 跟據切片型別和容量計算要分配記憶體的大小

var overflow bool

var lenmem, newlenmem, capmem uintptr

switch

// ...code...

// 將舊切片的資料搬到新切片開闢的位址中

memmove(p, old.array, lenmem)

return slice

}

3.切片擴容的內部實現

擴容1:切片擴容後其容量不變

slice := int

// 建立新的切片,其長度為 2 個元素,容量為 4 個元素

myslice := slice[1:3]

// 使用原有的容量來分配乙個新元素,將新元素賦值為 40

執行上面**後的底層資料結構如下圖所示:

擴容2:切片擴容後其容量變化

// 建立乙個長度和容量都為 5 的切片

myslice := int

// 向切片追加乙個新元素,將新元素賦值為 6

執行上面**後的底層資料結構如下圖所示:

四、小結

切片是乙個結構體,儲存著切片的容量,長度以及指向陣列的指標(陣列的位址)。

Go語言 切片長度和容量

package main import fmt func main printslice s slice the slice to give it zero length.s s 0 printslice s extend its length.fmt.println s 5 s s 4 print...

go語言中切片的長度和容量的區別

切片的長度,顯而易見的就是元素的個數,根據元素的個數進行返回具體的長度。切片的長度,更像是乙個警戒值,如果長度與容量相等,就會進行容量的擴容,比如 des makwww.cppcns.come int 3 5 程式設計客棧 此時,長度為3,容量為5,但是如果使用append 切片長度會變為4,再次使...

Go 陣列和切片

陣列擷取 a 開始索引位置,結束索引 切片 slice 是本身並非動態陣列和陣列指標,通過內部指標指向底層陣列。建立乙個length和capacity都等於5的slice slice make int,5 length 3,capacity 5的slice slice make int,3,5 建立...