首頁 > 後端開發 > Golang > 在這個 Go 程式碼範例中,為什麼 Loop1 會列印「更新」三次,而 Loop2 會列印不同的值?

在這個 Go 程式碼範例中,為什麼 Loop1 會列印「更新」三次,而 Loop2 會列印不同的值?

Linda Hamilton
發布: 2024-12-11 03:53:14
原創
458 人瀏覽過

Why Does Loop1 Print

理解 Go 中的 For 循環行為

在程式設計中,某些構造可能會導致意外的行為。考慮 for 迴圈的這兩種變體:

var cmds = []string{"create", "delete", "update"}

func loop1() {
    actions := make(map[string]func())

    for _, cmd := range cmds {
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
    for _, action := range actions {
        action()
    }
}

func loop2() {
    actions := make(map[string]func())

    for i, cmd := range cmds {
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
    for _, action := range actions {
        action()
    }
}
登入後複製

Loop1 列印「update」三次,而 Loop2 列印「delete」、「update」和「create」。為了理解這種行為,讓我們深入研究細節。

循環變數參考

在loop1中,我們聲明一個循環變數cmd並使用它來迭代cmds切片。然而,在嵌套循環中,變數 cmd 仍然引用外層循環中的循環變數。

閉包中的值共享

在映射中建立函數文字時actions 中,循環變數 cmd 被閉包捕獲。這意味著每個函數繼承對同一循環變數實例的引用,而不是副本。

Last Value Dependency

當巢狀循環完成時,循環變數 cmd 已前進到切片中的最後一個元素(「更新」)。這意味著所有閉包現在都引用最後一個元素。

結果:

在嵌套循環內打印時,所有閉包都會打印“update”,因為它們都引用中的最後一個元素相同

修正:

要解決此問題,我們使用cmd2 := cmd 在 Loop1 中建立循環變數的副本,並在函數文字中使用該副本。這確保每個閉包在建立時都對 cmd 的值有一個不同的參考。

這一澄清強調了在閉包中引用循環變量的細微差別,並演示了仔細理解閉包如何在 Go 中捕獲變量的重要性.

以上是在這個 Go 程式碼範例中,為什麼 Loop1 會列印「更新」三次,而 Loop2 會列印不同的值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板