回答編集履歴

1

コメントで補足した点を記述

2020/09/28 04:02

投稿

d_tutuz
d_tutuz

スコア730

test CHANGED
@@ -83,3 +83,71 @@
83
83
  m: map[0:[0] 1:[100] 2:[200] 3:[300] 4:[400] 5:[500] 6:[600] 7:[700] 8:[800] 9:[900]]
84
84
 
85
85
  ```
86
+
87
+
88
+
89
+
90
+
91
+ #### 追記
92
+
93
+
94
+
95
+ for loop上の変数をgoroutineで並行処理する場合には注意が必要です。以下のコードは正しく動きません。
96
+
97
+
98
+
99
+ ```go
100
+
101
+ package main
102
+
103
+
104
+
105
+ import (
106
+
107
+ "fmt"
108
+
109
+
110
+
111
+ "golang.org/x/sync/errgroup"
112
+
113
+ )
114
+
115
+
116
+
117
+ func main() {
118
+
119
+ g := errgroup.Group{}
120
+
121
+ s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
122
+
123
+
124
+
125
+ for _, v := range s {
126
+
127
+ // v := v としてループごとに独立したアドレスで値を確保する必要があります
128
+
129
+ g.Go(func() error {
130
+
131
+ fmt.Printf("value: %d\n", v)
132
+
133
+ return nil
134
+
135
+ })
136
+
137
+ }
138
+
139
+
140
+
141
+ g.Wait()
142
+
143
+ }
144
+
145
+ ```
146
+
147
+
148
+
149
+ 上記の for range 内で宣言している値のアドレスはループごとに独立ではなく、 **同じ** アドレスを共有しています。そして、それぞれのgoroutineではクロージャで変数の "アドレス" を参照しています。つまりgoroutineで変数の値を参照するときに競合状態になっています。
150
+
151
+
152
+
153
+ ループごとの独立した変数のアドレスを確保しなおす必要があります。