深入理解Go語言中的陣列和切片

2022-09-24 21:06:16 字數 2940 閱讀 1753

一、型別

陣列是值型別,將乙個陣列賦值給另乙個陣列時,傳遞的是乙份拷貝。

切片是引用型別,切片包裝的陣列稱為該切片的底層陣列。

我們來看一段**

//a是乙個陣列,注意陣列是乙個固定長度的,初始化時候必須要指定長程式設計客棧度,不指定長度的話就是切片了

a := [3]int

//b是陣列,是a的乙份拷貝

b := a

//c是切片,是引用型別,底層陣列是a

c := a[:]

for i := 0; i < len(a); i++

//改變a的值後,b是a的拷貝,b不變,c是引用,c的值改變

fmt.println(a) //[2,3,4]

fmt.println(b) //[1 2 3]

fmt.println(c) //[2,3,4]

二、make

make 只能用於slice,map和channel, 所以下面一段**生成了乙個slice,是引用型別

s1 := make(int, 0, 3)

for i := 0; i < cap(s1); i++

s2 := s1

for i := 0; i < len(a); i++

fmt.println(s1) //[1 2 3]

fmt.println(s2) //[1 2 3]

三、當對slice append 超出底層陣列的界限時

//n1是n2的底層陣列

n1 := [3]int

n2 := n1[0:3]

fmt.println("address of items in n1: ")

for i := 0; i < len(n1); i++

//address of items in n1:

//0xc20801e160

//0xc20801e168

//0xc20801e170

fmt.println("address of items in n2: ")

for i := 0; i < len(n2); i++

//address of items in n2:

//0xc20801e160

//0xc20801e168

//0xc20801e170

//對n2執行append操作後,n2超出了底層陣列n1的j

n2 = append(nxbfvip2, 1)

fmt.println("address of items in n1: ")

for i := 0; i < len(n1); i++

//address of items in n1:

//0xc20801e160

//0xc20801e168

//0xc20801e170

fmt.println("address of items in n2: ")

for i := 0; i < len(n2); i++

//address of items in n2:

//0xc20803a2d0

//0xc20803a2d8

//0xc20803a2e0

//0xc20803a2e8

四、引用「失效」

實現了www.cppcns.com刪除slice最後乙個item的函式

func rmlast(a int)

呼叫此函式後,發現原來的slice並沒有改變

func main()

fmt.printf("[main] the address of xyz is %p\n", xyz)

rmlast(xyz)

fmt.printf("[main] after remove, the address of xyz is %p\n", xyz)

fmt.printf("%v", xyz) //[1 2 3 4 5 6 7 8 9]

}列印出來的結果如下:

[main] the address of xyz is 0xc2080365f0

[rmlast] the address of a is 0xc2080365f0

[rmlast] after remove, the address of a is 0xc2080365f0

[main] after remove, the address of xyz is 0xc2080365f0

[1 2 3 4 5 6 7 8 9]

這裡直接列印了slice的指標值,因為slice是引用型別,所以指標值都是相同的,我們換成列印slice的位址看下

func rmlast(a int)

func main()

fmt.printf("[main] the address of xyz is %p\n", &xyz)

rmlast(xyz)

fmt.printf("[main] after remove, the address of xyz is %p\n", &xyz)

fmt.printf("%v", xyz) //[1 2 3 4 5 6 7 8 9]

}結果:[main] the address of xyz is 0xc20801e1e0

[rmlast] the address of a is 0xc20801e200

[rmlast] after remove, the address of a is 0xc20801e200

[main] after remove, the address of xyz is 0xc20801e1e0

[1 2 3 4 5 6 7 8 9]

這次可以看到slice作為函式引數傳入函式時,實際上也是拷貝了乙份slice,因為slice本身是個指標,所以從現象來看,slice是引用型別

總結本文標題: 深入理解go語言中的陣列和切片

本文位址: /jiaoben/golang/163136.html

Go語言學習8 深入理解切片slice

slice是個結構體,原始碼如下 runtime slice.go type slice struct slice 共有三個屬性 注意,底層陣列是可以被多個 slice 同時指向的,因此對乙個 slice 的元素進行操作是有可能影響到其他 slice 的。建立 slice 的方式有以下幾種 序號方式...

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語言中陣列與切片的區別

一句話總結 切片是動態陣列,注意兩者初始化和函式引數的區別 1 初始化 陣列需要指定大小,不指定也會根據初始化的自動推算出大小,不可改變 陣列 a int a 3 int 切片 a int a make int,5 a make int,5,10 var a int int errora intva...