For ループと匿名関数を使用した Go 同時実行の予期せぬ動作を理解する
Go で、for ループを使用して匿名のゴルーチンを作成する場合関数を実行すると、予期しない動作が発生し、すべてのゴルーチンが同じ値を出力する可能性があります。この動作を理解するために、次のコードを分析してみましょう:
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func() { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }() } wg.Wait() }
驚くべきことに、このコードは、予想される "2, 4, 1, 5," の代わりに "6, 6, 6, 6, 6" を出力します。 3.」この異常は、匿名関数によって作成されたクロージャに起因すると考えられます。
Go では、クロージャは周囲のスコープから変数をキャプチャする関数です。上記のコードでは、各匿名関数が変数 i をキャプチャします。ただし、for ループが反復されると、i はすでに 5 になります。これは、すべてのクロージャが同じ i の値、つまり 6 をキャプチャすることを意味します。
この問題を解決するには、i を引数として渡すことができます。無名関数。そうすることで、各クロージャによってキャプチャされる i のローカル コピーを作成し、各ゴルーチンが正しい値を出力するようにします:
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func(i int) { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }(i) } wg.Wait() }
以上が匿名関数を使用した Go 同時実行ループで同じ値が出力されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。