Go 切片的意外追加行为:解释
在 Go 中,append 函数在追加到指针切片时的行为很有趣。为了说明这一点,请考虑以下代码:
与代码打印 {0} {1} {2} {3} 的预期相反,它反而打印 {0} {3} { 3} {3}。这种差异背后的原因在于 for 循环范围变量的性质。
理解范围变量
Go 中的 for-range 循环通过创建一个副本来操作正在迭代的数组或切片中的每个元素。在本例中,e 是数组 b 中元素的副本。因此,e 本身不是 b 中的元素;相反,它是一个保存元素值的临时变量。
追加到切片 a 时,代码追加的是 e 的地址,而不是 b 中实际元素的地址。由于 e 对于所有迭代都是相同的副本,因此相同的指针会被附加到 a 三次。因此,分配给 e 的最后一个值(即 Foo{3})是重复打印的值。
修复行为
要纠正此行为,代码应附加 b 中实际元素的地址,而不是 e 的地址。更正后的循环如下所示:
通过附加 &b[i] 而不是 &e,代码确保 b 中的每个元素都添加到 a 中。因此,会打印正确的输出 {0} {1} {2} {3}。
初始行为的原因
此意外行为源于缺少Go 中的真实引用。 Go 有指针类型和非指针类型,但没有引用。范围变量只是一个局部变量,保存的值可以是指针或非指针。它不能保存引用。
因此,在操作范围变量时,只是操作值,而不是操作元素本身。要修改实际元素,必须将值分配给范围变量,从而有效地复制该值。然后该值将在下一次迭代中被覆盖。
以上是为什么 Go 的'append”函数在从 for-range 循环追加指针时会产生意外结果?的详细内容。更多信息请关注PHP中文网其他相关文章!