引用还是复制?看看 Golang 中诡异的切片操作

切片赋值,实际上只是复制了地址:

b := a

b 引用了 a 的地址。因此,b 的任何修改,都会影响 a。
但是,如果 b 扩容了,b 就会新申请空间,把数据复制到新空间。b 与 a 就没啥关系了。
感觉 Golang 的这个设计真是很烂!因为我们在设计阶段无法预知两个切片操作是否共用一块内存,对变量 b 的操作是否对变量 a 产生副作用,设计阶段无法准确判定。在一款新型的程序设计语言中还会出现这样的“副作用”机制,让人感到很遗憾。

package main

import (
	"fmt"
)

func main() {
	a := []int{0, 1, 2, 3, 4}
	b := a
	b[0] = 111 //此处修改,a[0]同时修改

	fmt.Println(a)
	fmt.Println(b)

	fmt.Println("---------------------")

	b = append(b, 0) //b扩容后,不再与a共享内存
	b[0] = 222       //此处修改,a[0]不受影响
	fmt.Println(a)
	fmt.Println(b)

	fmt.Println("---------------------")
	c := make([]int, len(a))
	copy(c, a)
	c[0] = 333 	//此处修改,a[0]不受影响
	fmt.Println(a)
	fmt.Println(c)
}

>>运行结果:
C:/Users/Administrator/slice/slice.exe  [C:/Users/Administrator/slice]
[111 1 2 3 4]
[111 1 2 3 4]
---------------------
[111 1 2 3 4]
[222 1 2 3 4 0]
---------------------
[111 1 2 3 4]
[333 1 2 3 4]
成功: 进程退出代码 0.

建议切片复制,还是用 copy 命令吧,直接复制数据,断绝关联。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许野平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值