引用还是复制?看看 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 命令吧,直接复制数据,断绝关联。

你可能感兴趣的:(golang,Golang,引用,复制,切片)