回答編集履歴
1
コメントで補足した点を記述
answer
CHANGED
@@ -40,4 +40,38 @@
|
|
40
40
|
|
41
41
|
```
|
42
42
|
m: map[0:[0] 1:[100] 2:[200] 3:[300] 4:[400] 5:[500] 6:[600] 7:[700] 8:[800] 9:[900]]
|
43
|
-
```
|
43
|
+
```
|
44
|
+
|
45
|
+
|
46
|
+
#### 追記
|
47
|
+
|
48
|
+
for loop上の変数をgoroutineで並行処理する場合には注意が必要です。以下のコードは正しく動きません。
|
49
|
+
|
50
|
+
```go
|
51
|
+
package main
|
52
|
+
|
53
|
+
import (
|
54
|
+
"fmt"
|
55
|
+
|
56
|
+
"golang.org/x/sync/errgroup"
|
57
|
+
)
|
58
|
+
|
59
|
+
func main() {
|
60
|
+
g := errgroup.Group{}
|
61
|
+
s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
62
|
+
|
63
|
+
for _, v := range s {
|
64
|
+
// v := v としてループごとに独立したアドレスで値を確保する必要があります
|
65
|
+
g.Go(func() error {
|
66
|
+
fmt.Printf("value: %d\n", v)
|
67
|
+
return nil
|
68
|
+
})
|
69
|
+
}
|
70
|
+
|
71
|
+
g.Wait()
|
72
|
+
}
|
73
|
+
```
|
74
|
+
|
75
|
+
上記の for range 内で宣言している値のアドレスはループごとに独立ではなく、 **同じ** アドレスを共有しています。そして、それぞれのgoroutineではクロージャで変数の "アドレス" を参照しています。つまりgoroutineで変数の値を参照するときに競合状態になっています。
|
76
|
+
|
77
|
+
ループごとの独立した変数のアドレスを確保しなおす必要があります。
|