在 Go 中,for 循环不像 C# 中的 foreach 循环,循环变量在循环体内不能更改。在 Go 中,循环变量是可以修改的,从而需要以不同的方式处理捕获的闭包行为。
为了说明这一点,让我们检查三个代码片段:
实验室1:
l := [](func() (int32, int32)){} for k, v := range m { // Closure captures the last values assigned to k and v from the range l = append(l, func() (int32, int32) { return k, v }) }
实验室2:
l := [](func() (int32, int32)){} for k, v := range m { // Closure captures the outer variables k and v (which are modified in the loop) l = append(l, func() (int32, int32) { return k, v }) }
实验室3:
l := [](func() (int32, int32)){} for k, v := range m { kLocal, vLocal := k, v // Captures just the values assigned to k and v at the iteration l = append(l, func() (int32, int32) { return kLocal, vLocal }) }
在 Lab1 和 Lab2 中,闭包捕获分配给循环体内循环变量的最后一个值。如果在循环内修改循环变量,可能会导致错误的结果。
Lab3 演示了正确的方法。它使用局部变量捕获每次迭代中专门分配给循环变量的值。这种行为与 Go 中的闭包一致,其中捕获的变量默认是引用透明的。
在 Go 中,for 循环变量上的闭包捕获值而不是引用。为了捕获循环期间可能发生变化的值,有必要在每次迭代中创建局部变量,将所需的值分配给闭包。这种方法确保关闭行为符合预期。
以上是Go 闭包如何处理 For 循环变量并防止意外行为?的详细内容。更多信息请关注PHP中文网其他相关文章!