ホームページ > バックエンド開発 > Golang > Go の「for range」ループが関数リテラルで異なる動作を示すのはなぜですか?

Go の「for range」ループが関数リテラルで異なる動作を示すのはなぜですか?

Susan Sarandon
リリース: 2024-12-10 20:52:11
オリジナル
430 人が閲覧しました

Why Does Go's `for range` Loop Exhibit Different Behavior with Function Literals?

Go のさまざまなループの動作を理解する

Go でループを構築する場合、for range ループの動作を理解することが重要です。異なる動作を示す次の 2 つのループ バリエーションを考えてみましょう:

ループ バリエーション 1:

func loop1() {

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

    for _, cmd := range cmds {
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
    for _, action := range actions {
        action()
    }
}
ログイン後にコピー

ループ バリエーション 2:

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()
    }
}
ログイン後にコピー

出力観測:

  • ループ 1 は出力を生成します: "更新" (3 回繰り返します)
  • ループ 2 は出力を生成します: "削除"、"更新"、"作成"

ループ バリエーションの根本的な問題1:

問題は funcloop1() ループにあります。各ループ反復では、関数リテラルがアクション マップに割り当てられます。この関数リテラルはループ変数 cmd を参照します。ただし、cmd のインスタンスは 1 つだけであり、ループが終了すると、コマンド スライスの最後の値である「update」が保持されます。これは、囲まれたすべての関数が同じループ変数 (cmd) を参照することを意味し、その結果、呼び出されたときにすべての関数が「update」を出力します。

解決策:

これを修正するには、各ループ反復内でループ変数のコピーを作成するため、各関数リテラルは独自の独立したリテラルを持ちます。 copy:

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

    for _, cmd := range cmds {
        cmd2 := cmd
        actions[cmd] = func() {
            fmt.Println(cmd2) // Refer to the detached, copy variable!
        }
    }
    for _, action := range actions {
        action()
    }
}
ログイン後にコピー

結論:

結論として、for range ループを使用する場合は、ループ変数のスコープと参照を考慮することが重要です。必要なときにループ変数のコピーが作成されるようにすることで、特にそれらの変数を参照する関数リテラルを扱う場合に、正しい動作が保証されます。

以上がGo の「for range」ループが関数リテラルで異なる動作を示すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート