データ競合におけるゴルーチンの動作を理解する
提供されたコード スニペットは、Go における古典的なデータ競合の問題を示しています。目的はフィールドのリストから異なる値 (「one」、「two」、「three」) を出力することですが、実際の結果では「three」が 3 回出力されます。
これを解決するにはこの問題を解決するには、データ競合が発生する理由と場所を理解する必要があります。
データ競合の特定
問題は、 goroutine関数の引数の評価。ループがデータ スライスを反復処理するとき、範囲変数 v がループ本体に割り当てられ、v.print() の呼び出しで使用されます。ただし、 v 変数は要素のコピーであり、スライスは反復中に変更されるため、最終的にはすべてのゴルーチンがスライスの同じ最後の要素を指すことになります。
これは、ゴルーチンが実行されるときに、これらはすべて、意図した一意の値 (「one」、「two」、「three」) ではなく、最後の値 (「three」) を出力します。
可能解決策
この問題に対処してデータ競合を解消するには、いくつかの方法があります:
ループ内に新しい変数を作成します:
ポインターのスライスを使用します:
スライス要素のアドレスを渡します:
引数を持つ匿名関数の使用:
これらのソリューションのいずれかを適用することで、データ競合を排除し、ゴルーチンが意図した一意の値 ("one"、 「2」、「3」) 順序は任意です。
以上がGo でスライスを使用しているにもかかわらず、ゴルーチンがすべて同じ値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。