ホームページ > バックエンド開発 > C++ > ループ内のラムダ式が予期しない結果を生み出すのはなぜですか?

ループ内のラムダ式が予期しない結果を生み出すのはなぜですか?

Linda Hamilton
リリース: 2025-01-14 11:26:46
オリジナル
721 人が閲覧しました

Why Do Lambda Expressions in Loops Produce Unexpected Results?

ラムダ式とループ反復変数: 潜在的な落とし穴

ループ反復変数をラムダ式内で直接使用することは、一般に推奨されません。 この方法では、ラムダ式による変数キャプチャの処理方法により、予期しない結果が生じる可能性があります。

ラムダ式は、キャプチャ時の値ではなく、変数への参照をキャプチャします。 したがって、ループが反復されると、ループ内で作成されたラムダ式はすべて、同じ、常に変化する反復変数を参照します。 これにより、すべてのラムダは最終的に、各ラムダの作成時の値ではなく、ループ完了後の変数の final 値を使用することになります。

VB.NET の例でこれを説明してみましょう:

<code class="language-vb.net">Dim actions = new List(Of Action)()

For i As Integer = 0 To 9
    actions.Add(New Action(Function() Console.WriteLine(i)))
Next

For Each action As Action In actions
    action()
End For</code>
ログイン後にコピー

これでは 0 から 9 が出力されると思われるかもしれませんが、代わりに 10 が 10 回出力されます。これは、Action リスト内の各 actions が同じ i を参照しており、2 番目のループが実行される時点で、i がすでに最終値 10 に達しているためです。

ループ本体にラムダ式で参照される変数に影響を与える副作用がある場合、問題はさらに拡大します。 これにより、デバッグが困難な不整合が発生する可能性があります。

解決策: ローカル コピーを作成する

これを防ぐには、ループ

に反復変数のローカル コピーを作成します。

<code class="language-vb.net">Dim actions = new List(Of Action)()

For i As Integer = 0 To 9
    Dim localI As Integer = i ' Create a local copy
    actions.Add(New Action(Function() Console.WriteLine(localI)))
Next

For Each action As Action In actions
    action()
End For</code>
ログイン後にコピー
各ラムダ式は一意の

変数をキャプチャし、作成時の値を保持します。 出力は正しく 0 ~ 9 になります。この簡単な変更により、各ラムダが独自の独立した値で動作することが保証され、予期しない動作が回避されます。localI

以上がループ内のラムダ式が予期しない結果を生み出すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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