在提供的代码中,两个循环变体表现出不同的行为当访问切片中的元素时。 Loop1 重复返回“update”,而 Loop2 则打印预期的“删除”、“更新”和“创建”序列。
理解这种差异的关键在于循环变量 (cmd) 在闭包 (func()) 中使用的方式。在 Loop1 中,对循环变量的引用存储在闭包中。这意味着对 cmd 的任何后续更改都将影响映射中的所有闭包。
当第二个循环执行时,cmd 的值已更新为“update”,即 cmds 切片中的最后一个元素。因此,映射中的所有闭包都会引用最后一个值,从而导致重复的“更新”输出。
然而,在 Loop2 中,循环变量的副本是存储在闭包中。这将创建一个独立变量,该变量不受原始 cmd 的后续更改的影响。循环的每次迭代都会为 cmd2 分配一个不同的值,然后闭包会引用该值。
因此,第二个循环正确打印 cmds 切片的每个元素。
为了避免此类引用问题,通常建议在访问闭包内的元素时使用切片的索引而不是循环变量。这样,无论循环变量如何更改,每个闭包都可以访问正确的元素。
范围循环返回的第二个值(元素的副本)当您想要将值传递给单独的 goroutine 或线程而不用担心对原始变量的并发访问时,这会很有用。这使得需要共享数据的任务变得很方便,而不必担心损坏源。
以上是为什么 Golang 的循环行为在使用引用和循环变量副本时有所不同?的详细内容。更多信息请关注PHP中文网其他相关文章!