深入解析Go語言 (二)切片slice

2021-09-10 01:32:32 字數 1985 閱讀 4014

我們都知道go中slice切片是不同於陣列的資料型別,他的亮點在在於它是引用型別,那麼它是如何實現引用的呢?

首先我們先來明確一下他的結構,乙個slice是包含 3個域的結構體,分別是:指向slice中的第乙個元素的指標,slice的長度,以及slice的容量。區分一下長度和容量,長度是下表操作的上界,如x[i]中的i必須小於長度;容量是分割操作的上界,如x[i:j]中j不能大於容量。

定義乙個切片時,並不會複製乙份資料,而是會建立乙個新的資料結構,像上面寫的那樣,指標指向的是同乙個底層陣列,舉個例子:

a:=int

b :=a[1:3]

a的切片裡有五個元素,定義乙個slice b擷取a的1,2位置的值(注意在切片操作時,x[i:j]是不包括下標為j的值得),所以b中的結構中第乙個元素就是乙個指向底層陣列下標為1元素的指標,但是在新的切片中索引不收原來陣列的影響,即b[0]=2;

既然是引用型別,那麼就說明修改b或a中任意乙個相同的值,都會發生改變,讓我們驗證一下

a:=int

b :=a[1:3]

b[0]=6

fmt.println(a)

fmt.println(b)

結果:

[1 6 3 4 5]

[6 3]

slice的擴容:

我們用例子說明一下:

a:=int

b :=a[1:3]

fmt.println(cap(b))

fmt.println(cap(b))

結果:44

一開始b的容量為4,這與原來的陣列容量有關係,a中一共有五個元素,預設容量為5,b擷取的時下標1開始的,所以預設容量為4,這時候b中有兩個元素,再增加兩個,沒超出,但是如果我們在增加乙個呢?

a:=int

b :=a[1:3]

fmt.println(cap(a))

fmt.println(cap(b))

fmt.println(cap(b))

fmt.println(cap(b))

結果:54

48很明顯容量增加了一倍;修改一下,驗證一下上面第一點

a:=int

b :=a[1:3]

fmt.println(cap(a))

fmt.println(cap(b))

fmt.println(cap(b))

有上面,我們知道b的容量為4,所以增加七個元素後,一共有9個元素,變成了容量的2倍以上,我們看一下結果:

容量變成了10,這裡長度時9,這種情況下擴容後比實際具有的總長度還要大一些。

再來說一下定義乙個切片的時候:可以用new和make,有什麼區別呢?

首先乙個最基本的區別就是:new()返回的是乙個指標

我們先來介紹一下new(),他一般用於引用型變數定義的時候,給你定義的型別分配一塊記憶體,然後返回乙個執行這個記憶體的位址,他只需要乙個引數,就是type,同時請注意它同時把分配的記憶體置為零,也就是型別的零值。

我們舉個例子感受一下:

當我們定義乙個指標,如果沒有new,直接賦值的話就會出現錯誤,*a就是他的值,a就是乙個位址。好處就是,利用new不用進行初始化

make:

make也是用於記憶體分配的,但是和new不同,它只用於chan、map以及切片的記憶體建立,而且它返回的型別就是這三個型別本身,而不是他們的指標型別,因為這三種型別就是引用型別,所以就沒有必要返回他們的指標了。

看一下他的函式宣告:

func make(t type, size ...integertype) type

很明顯他要進行初始化,引數增加,並且返回的時他本身的型別

go語言切片深入講解

package main import fmt func change s int func main change slice fmt.println slice 我們先來看一下結果 我們可以看到切片當作函式引數的時候呼叫之後值確實改變了,這也間接的可以認為切片是位址傳遞,但是我們想要了解的更深入...

深入解析Go語言程式設計中slice切片結構

陣列轉換成切片 複製 如下 a 10 int fmt.println a s1 a 10 取前10個元素 5 取 5 最後的元素 fmt.println s1 slice測試 複製 如下 a byte sa a 2 5 fmt.println string sa sd1 a 3 5 fmt.prin...

Go語言切片

go語言切片 go語言切片是對陣列的抽象 go 陣列的長度不可改變,在特定場景中這樣的集合就不太適用,go中提供了一種靈活,功能強悍的內建型別切片 動態陣列 與陣列相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。宣告乙個未指定大小的陣列來定義切片 var identifier ...