Go语言中 数组和slice 走过的坑

数组和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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值