Go語言中關於切片容量與其底層指標的思考

2021-08-22 13:46:04 字數 2632 閱讀 8419

go語言中的切片是常用的一種資料型別,其中切片的底層是陣列,切片常用的屬性有長度和容量。

其中長度很容易理解,但是容量相對複雜一些。

切片提供了計算容量的函式cap()可以測量切片最長可以達到多少:它等於切片的長度 + 陣列除切片之外的長度。

以下有幾個例項,第一:

slice := int

newslice := slice[1:3]

testslice := slice[1:2]

fmt.println("cap slice:", cap(slice))

fmt.println("cap newslice:", cap(newslice))

fmt.println("cap test:", cap(testslice))

分別列印什麼呢?

答案是:

cap slice: 5

cap newslice: 4

cap test: 4

首先,我們看slice的宣告方法,直接宣告了乙個元素為int的切片,並且賦值,可以理解為底層是乙個5個元素的陣列,所以slice的容量為5,那麼從slice上擷取得到的newslice和testslice長度不同,為何容量是一樣的呢?我們看下邊這張圖:

其中切片y是x從下標1開始,長度為2,容量為4,指標指向的位置為切片的起始位置,所以不難理解,為什麼前乙個例子總newslice與testslice的容量為何相同了,是因為底層陣列的長度是一樣的。可以簡單記憶為:切片的容量是只與切片的起始下標有關,是底層陣列減去起始位置。

再看第二個例子:

源自文章: 

我們常見的切片中只包含乙個冒號,用來標識起始位置與結束位置(左閉右開),起始從go1.2起,支援第三個引數,用來指定該切片的容量,如上圖所示,有切片slice[i:j:k],其中切片的長度為j-i,容量為k-i。

接下來是第三個例項:

**於stack overflow 

package main

import "fmt"

func main()

func printslice(s string, x int)

會輸出什麼呢?

答案是:

a len=0 cap=0 

a len=1 cap=1 [0]

a len=2 cap=2 [0 1]

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

這裡邊包含了切片長度擴充套件的原則:

當切片容量難以滿足切片長度時,需要進行擴容,由於增加切片容量需要消耗效能,所以go預設的是會將切片的容量提高一倍,類似於網路中視窗大小每次也是乘以二。

a len=9 cap=10 [0 1 2 3 4 5 6 7 8]
package main

import "fmt"

func main()

func printslice(s string, x int)

列印結果如下:

a len=0 cap=0 

a len=1 cap=1 [0]

a len=2 cap=2 [0 1]

a len=3 cap=4 [0 1 2]

a len=4 cap=4 [0 1 2 3]

a len=5 cap=8 [0 1 2 3 4]

可以看到,切片的容量是0->1->2->4->8,當切片容量不足時,繼續新增元素容量會擴大一倍。

最後乙個例項,其實與之前一篇關於切片是否是傳引用呼叫的博文有關,有興趣的同學可以翻看一下

先看**:

package main

import (

"fmt"

)func main()

newslice := slice[1:3]

// 使用原有切片劃分出新切片,容量為4

// 將新元素賦值為 60,會改變底層陣列中的元素

fmt.println(newslice)

fmt.println(slice)

slice1 := int

newslice1 := slice1[1:3:3] // 新切片容量為2

fmt.println(newslice1)

fmt.println(slice1)

}

列印的結果如下:

[20 30 60]

[10 20 30 60 50]

[20 30 60]

[10 20 30 40 50]

為什麼第一次會影響原切片,而第二次不會呢?

以上都是切片中的一些細節性問題,如有問題還請各位指正

GO語言中的切片

宣告乙個切片int型的切片 var s int 初始化乙個長度為len,容量為cap的切片 s make int,len,cap cap可以省略,省略後cap等於len 也可以簡潔的初始化 s make int len,cap 還可以指定值的建立切片 s int 指定索引值式的建立 s int 索引...

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

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

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