在 Go 中,我正试图打乱我的旅行者问题slices功能。在执行此操作时,我注意到,当我开始编辑切片时,每次输入时,我都会给出不同的加扰功能。 4 B& C' t- i8 D经过一些调试,我发现这是因为我编辑了函数slices。但既然 Go 应该是 pass by value语言,这怎么可能? : M* n A/ n3 r+ Jhttps://play.golang.org/p/mMivoH0TuV 8 E1 o7 t0 A4 C我提供了一个操场链接来解释我的意思。通过删除第 27 线,您将获得与保留它不同的输出,因为该函数应该在作为参数输入时制作自己的切片副本。/ l! k. L, z. B' U
有人能解释这种现象吗? : S. J, y$ r* `( d1 H6 m 5 R0 C9 _8 ^6 B8 }7 y" H' c! R 解决方案: 7 i/ @" M1 L' p$ P* I Go 中的所有内容都是按值传递的,切片也是如此。但切片值是一个header,描述了支持数组的连续部分,切片值仅包含指向实际存储元素的指针。切片值不包括其元素(不同于数组)。7 h- y) g D% Z8 p+ H% K
因此,当您将切片传输到函数时,从标头创建一个副本,包括指向同一备份数组的指针。修改切片的元素意味着修改支持数组的元素,因此共享相同支持数组的所有切片都将观察更改。$ `5 ]& ^' |, V$ X3 k1 \- V3 ^8 z
检查切片标头的内容,请检查reflect.SliceHeader类型: % B9 E- p6 F7 \3 e/ c$ U. ^5 P
type SliceHeader struct Data uintptr Len int Cap int} 9 J1 i) q% s& w6 p: C