2016-05-31 4 views
0

変数iteratating iに基づいてゴルーチン内で条件チェックを行っていて、期待していなかった結果が得られたことがわかりました。コード。ゴルーチンを使用して反復すると予期せぬ結果が出る

for i := 1; i <= 5; i++ { 
    wg.Add(1) 
    fmt.Println(i) 

    go func() { 
     fmt.Println(i) 
     wg.Done() 
    }() 


} 
wg.Wait() 

1 
2 
3 
4 
5 
6 
6 
6 
6 
6 

この現象は予期しないものですか?誰かがなぜ6が5回印刷されているのかを親切に説明できますか?

+1

よくある質問:https://golang.org/doc/faq#closures_and_goroutines – JimB

+0

より正確な重複:http://stackoverflow.com/questions/36776315/go-concurrency-with-for-loop- and-anonymous-function-behaves-unexpectedly – JimB

+0

6,6,6,6のみを取得する必要はありません。 iの値を大きくする。あなたは別の価値を得るでしょう。あなたはgoroutineの実行時にiの値を得ています。 – khrm

答えて

5

Playground example

あなたのすべてのゴルーチンは、あなたのためのループが終了した後に非同期で実行されています。あなたのループiのための終わりに

は6に等しく、したがって、あなたのゴルーチンは、それぞれあなたがクロージャを作成することができ、問題を解決し、内部iの現在の値を保存するには数6

を記録しますこれは、ゴルーチンが実行されるときに、適切な値のiで実行されるようにします。それはあなたがそのような後で、ときのためのことを実行するためにゴルーチンを言っている

go func(x int) { 
    fmt.Println(x) 
    wg.Done() 
}(i) // <--- "save" value of i at this point in time. 

ようにあなたは、関数内でiの値を「保存」をこのように見えますので、これはちょうどあなたのコードを変更行うに

ループが完了するまで実行されたが、の現在のの値はiであり、これは6ではありません。代わりに、の古いという値をiという値にして、ゴルーチンが作成された時点で使用します。

関連する問題