在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中文網其他相關文章!