Golang が変数を同時に共有する方法
この説明は、Go の複数のゴルーチン間で変数がどのように共有されるかを理解することに焦点を当てています。次のコードを考えてみましょう:
<code class="go">package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) x := i go func() { defer wg.Done() fmt.Println(x) }() } wg.Wait() fmt.Println("Done") }</code>
実行すると、期待された出力が得られます:
4 0 1 3 2
しかし、コードに微妙な変更が加えられると:
<code class="go">package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println(i) }() } wg.Wait() fmt.Println("Done") }</code>
結果の出力は予想外に均一です。
5 5 5 5 5
説明
主な違いは、ゴルーチン内の変数のスコープにあります。
In最初のコード スニペットでは、ループの各反復で新しい変数 x が作成され、その値がゴルーチンに渡されます。ゴルーチンが実行されると、x のローカル コピーが作成され、その初期値が出力されます。したがって、期待される出力が得られます。
ただし、2 番目のコード スニペットでは、すべてのゴルーチンが単一の変数 i を共有します。ゴルーチンが実行されると、ループの完了後に i の最終値が取得されます。その結果、すべてのゴルーチンは同じ値 5 を出力します。
影響とベスト プラクティス
この動作は、ゴルーチンを使用する場合の変数スコープの重要性を強調しています。スレッドセーフな実行を保証するには、変数のスコープを考慮し、必要に応じて (両方のコード スニペットで示されているように) 待機グループなどの同期プリミティブを活用することが重要です。
以上が変数を共有すると、Golang のゴルーチンが同じ値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。