数组和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