一、型別
陣列是值型別,將乙個陣列賦值給另乙個陣列時,傳遞的是乙份拷貝。
切片是引用型別,切片包裝的陣列稱為該切片的底層陣列。
我們來看一段**
//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...