數組和slice差別
在go語言中,數組是一段連續的記憶體,在初始化時候需要明确聲明其大小,不可以在運作時動态生成,而slice則可以自由得伸縮其大小。我們知道slice,底層其實就是一個數組。
指派差別
數組指派
go語言中,數組指派采用的是值指派方式,指派後的兩個數組互不影響
func arrayFuzhi(){
array1 := [3][3]int{{1,2,3},{4,5,6},{7,8,9}}
array2 := array1
array1[0][0]=0
fmt.Printf("array1 address:%p,array1[0][0]:%d\n",&array1,array1[0][0])
fmt.Printf("array2 address:%p,array2[0][0]:%d",&array2,array2[0][0])
}
運作結果
array1 address:0xc00000c1e0,array1[0][0]:0
array2 address:0xc00000c230,array2[0][0]:1
很明顯,兩個數組不受任何影響
slice指派
go語言中,slice指派采用的是位址指派方式,指派後的兩個slice使用的是同一個slice,指向同一個底層數組
func sliceFuzhi(){
array1 := [][]int{{1,2,3},{4,5,6},{7,8,9}}
array2 := array1
array1[0][0]=0
fmt.Printf("array1 address:%p,array1[0][0]:%d\n",array1,array1[0][0])
fmt.Printf("array2 address:%p,array2[0][0]:%d",array2,array2[0][0])
}
運作結果
array1 address:0xc00003a050,array1[0][0]:0
array2 address:0xc00003a050,array2[0][0]:0
很明顯,兩個slice的位址是一樣的,并且修改一個值,會影響另外一個slice。
slice複制
一維數組
現在我們有個需求,就是把現有的slice進行複制,并且讓兩個slice無影響,此時我們可以使用go内置函數copy來實作。
func sliceCopy(){
array1 := []int{1,2,3}
array2 := make([]int,len(array1))
array1[0]=99
fmt.Printf("array1 address:%p,array1[0]:%d\n",array1,array1[0])
fmt.Printf("array2 address:%p,array2[0]:%d",array2,array2[0])
}
運作結果
array1 address:0xc00009e140,array1[0]:99
array2 address:0xc00009e160,array2[0]:1
很明顯,兩個slice的位址是不一樣的,并且修改一個值,不會影響另外一個slice。
多元數組
以上是一維數組的複制,如果是二維或多元數組,則不生效,因為二維數組的裡面的一維數組還是slice,需要重新copy,是以,針對于二維數組,我們可以周遊源slice的每個元素,并添加到新的數組上去。
func sliceCopy_erwei(){
array1 := [][]int{{1,2,3},{4,5,6},{7,8,9}}
var array2 [][]int
for i:=0;i<len(array1);i++{
tmp:=make([]int,len(array1[i]))
copy(tmp,array1[i])
array2=append(array2,tmp)
}
array1[0][0]=99
fmt.Printf("array1 address:%p,array1[0][0]:%d\n",&array1[0][0],array1[0][0])
fmt.Printf("array2 address:%p,array1[0][0]:%d",&array2[0][0],array2[0][0])
}
運作結果
array1 address:0xc00009e140,array1[0][0]:99
array2 address:0xc00009e1a0,array1[0][0]:1