在 Go 中,我正在尝试为我的旅行商问题制作一个打乱slices功能。在执行此操作时,我注意到当我开始编辑切片时,每次传入时,我给的加扰功能都不同。
经过一些调试,我发现这是由于我在函数内编辑了slices。但既然 Go 应该是一种“pass by value”语言,这怎么可能呢?
https://play.golang.org/p/mMivoH0TuV
我提供了一个游乐场链接来说明我的意思。通过删除第 27 行,您会得到与保留它不同的输出,这应该没有区别,因为该函数应该在作为参数传入时制作自己的切片副本。 有人可以解释这种现象吗?
Go 中的所有内容都是按值传递的,切片也是如此。但是切片值是一个header,描述了支持数组的连续部分,并且切片值仅包含指向实际存储元素的数组的指针。切片值不包括其元素(与数组不同)。
因此,当您将切片传递给函数时,将从该标头创建一个副本,包括指向同一个后备数组的指针。修改切片的元素意味着修改支持数组的元素,因此共享相同支持数组的所有切片都将“观察”更改。
要查看切片标头中的内容,请查看reflect.SliceHeader类型:
reflect.SliceHeader
type SliceHeader struct { Data uintptr Len int Cap int }