質問するログイン新規登録

回答編集履歴

1

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

2020/09/28 04:02

投稿

d_tutuz
d_tutuz

スコア730

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
+ ループごとの独立した変数のアドレスを確保しなおす必要があります。