提供されたコードでは、2 つのループのバリエーションが異なる動作を示しています。スライスから要素にアクセスするとき。ループ 1 は「更新」を繰り返し返しますが、ループ 2 は予期されるシーケンスの「削除」、「更新」、「作成」を出力します。
この違いを理解する鍵は次のとおりです。ループ変数 (cmd) がクロージャー (func()) で使用される方法。 Loop1 では、ループ変数への参照がクロージャに格納されます。これは、その後の cmd への変更がマップ内のすべてのクロージャに影響することを意味します。
2 番目のループが実行されるとき、cmd の値はすでに cmd スライスの最後の要素である「update」に更新されています。したがって、マップ内のすべてのクロージャはこの最後の値を参照し、その結果、「更新」出力が繰り返されます。
ただし、ループ 2 では、ループ変数のコピーがクロージャー内に保管されます。これにより、元の cmd に対するその後の変更の影響を受けない切り離された変数が作成されます。ループの各反復では、異なる値が cmd2 に割り当てられ、クロージャーはそれを参照します。
その結果、2 番目のループは cmds スライスの各要素を正しく出力します。
このような参照の問題を回避するには、クロージャ内の要素にアクセスするときにループ変数の代わりにスライスのインデックスを使用することが一般的に推奨されます。このようにして、ループ変数への変更に関係なく、各クロージャは正しい要素にアクセスできます。
範囲ループによって返される 2 番目の値 (要素のコピー)元の変数への同時アクセスを気にせずに、値を別のゴルーチンまたはスレッドに渡したい場合に便利です。これにより、ソースの破損を心配せずにデータを共有する必要があるタスクに便利です。
以上がループ変数の参照を使用する場合とコピーを使用する場合で Golang のループ動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。