Go入門學習 理解區分陣列和切片

2022-04-07 17:21:33 字數 3098 閱讀 9868

學過 go 的都知道在 go 語言中有四種復合資料型別:陣列、切片(slice)、雜湊表(map)和結構體(struct),而很多 go 初學者也很容易把陣列和切片弄混淆,所以要怎麼把這兩個資料型別分清楚呢?

陣列是聚合型別,是一組同型別資料的集合,通過從0開始的下標索引訪問元素值。在 go 語言中,陣列是值型別,這就意味著當你將乙個陣列賦值給另乙個陣列的時候,實際上是將這個陣列拷貝了乙份。

陣列的宣告語法為:

var 陣列變數名 [元素數量]type

語法說明如下所示:

預設情況下,陣列的每個元素都被初始化為元素型別對應的零值,對於數字型別來說就是0。在陣列字面值中,如果在陣列的長度位置出現的是「...」省略號,則表示陣列的長度是根據初始化值的個數來計算。示例如下:

1

var a [3]int

2 a[0] = 1

3 b := [2]int

4 c := [...]int

5 fmt.println(a) //

[1 0 0]

6 fmt.println(b) //

[1 2]

7 fmt.println(c) //

[3 5 7]

陣列通過下標訪問元素,可修改其元素值。陣列的遍歷通過 for 迴圈實現:

1 arr := [3]int

2for i := 0; i < 3; i++ //

2 4 6

5fmt.println()

6for _, v :=range arr //

2 4 6

陣列的長度不可改變,在一定場合下就不太適用了,go 語言則提供了一種可以動態擴容的資料型別--切片(slice)。乙個切片型別通常會寫作 t,其中 t 代表切片中元素的資料型別,切片的語法和陣列類似,只是沒有固定長度。  

切片和陣列有如下區別:

1)和陣列相比,切片除了有長度(len),還有容量(cap),容量指切片當前可容納元素的最大數量。

2)陣列是值型別,切片是引用型別。

值型別和引用型別有什麼區別呢?在傳遞引數時,如果是值型別,對引數修改不會對原來的變數產生影響,但若是引用傳遞,對引數的修改也會影響到原始資料。示例如下:

1

package main23

import (4"

fmt"5)

67 func change(a [3]int, s int

) 12

13func main()

15 sli := int

16change(arr, sli)

17 fmt.println(arr) //

[2 4 6]

18 fmt.println(sli) //

[4 5 7]

19 }

切片的初始化可以通過陣列來實現,也可以通過內建函式 make() 來實現,在使用 make() 方法時還可以設定切片的容量,在追加元素時,若切片的容量不足,則會按切片的長度的二倍進行擴容。示例如下:

1 arr := [5]int

2 s1 := arr[2

:]3 fmt.println(s1) //

[3 4 5]

4 s2 :=arr[:]

5 fmt.println(s2) //

[1 2 3 4 5]

6 s3 := make(int, 3

)7 s3[0], s3[1], s3[2] = 2, 4, 6

8 fmt.println(s3) //

[2 4 6]

1 arr := [5]int

2var sli int

3for _, v :=range arr

6 fmt.println(sli) //

[1 2 3 4 5]

細心的人會發現原始碼中寫的是 elems,這是不是就意味著可以一次新增多個元素呢?試一試:

1

var sli int

)3 fmt.println(sli) //

[1 2 3]

1

var y int

2for i := 0; i < 10; i++

這幾行**的執行結果為:

0 cap=1 [0]

1 cap=2 [0 1]

2 cap=4 [0 1 2]

3 cap=4 [0 1 2 3]

4 cap=8 [0 1 2 3 4]

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

6 cap=8 [0 1 2 3 4 5 6]

7 cap=8 [0 1 2 3 4 5 6 7]

8 cap=16 [0 1 2 3 4 5 6 7 8]

9 cap=16 [0 1 2 3 4 5 6 7 8 9]

在 go 語言中,切片的拷貝使用內建函式 copy() 來實現,可以放心的是,切片拷貝是深拷貝,不用像 python 中糾結深淺拷貝真的很幸福呢!只不過拷貝的時候需要確保目的切片有足夠的容量,否則會拷貝。示例如下:

1 sli := int

2 res := make(int, 5)3

copy(res, sli)

4 fmt.println(res) //

[3 5 7 0 0]

5 fmt.println(&sli[0], &res[0]) //

0xc000012340 0xc00000c3c0

6var s int

7copy(s, sli)

8 fmt.println(s) //

這裡 s 列印出來是空的,是由於 s 在初始化的時候沒有分配記憶體空間,copy() 也不會為 s 分配空間,所以 sli 中的元素也就無法拷貝到 s 中了。

Go 陣列和切片

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

Go學習筆記 陣列和切片

陣列型別的值 以下簡稱陣列 的長度是固定的,而切片型別的值 以下簡稱切片 是可變長的。陣列的長度在宣告它的時候就必須給定,並且在之後不會再改變。可以說,陣列的長度是其型別的一部分。go 語言的切片型別屬於引用型別,同屬引用型別的還有後面會講到的字典型別 通道型別 函式型別等 而 go 語言的陣列型別...

Go學習筆記 陣列和切片

陣列 陣列是具有相同唯一型別的一組已編號且長度固定的資料項序列 同構的資料結構 這種型別可以是任意的原始型別,例如整型 字串或者自定義型別。陣列長度必須是乙個常量表示式,並且必須是乙個非負整數。陣列成都也是陣列型別的一部分,所以 5 int和 10 int是屬於不同型別的。陣列是一種值型別。陣列的編...