一個go閉包使用上的小坑
阿新 • • 發佈:2021-11-25
目錄
出處: http://www.cnblogs.com/ailumiyana/
除特別註明外,本站所有文章均為靑い空゛原創,歡迎轉載分享,但請註明出處。
一個go閉包使用上的小坑
無意間看到這樣一串程式碼:
m := make(map[int]int, 10)
for i := 1; i<= 10; i++ {
m[i] = i
}
for k, v := range(m) {
go func() {
fmt.Println("k ->", k, "v ->", v)
}()
好奇 跑了一下:
go run tmp.go k -> 7 v -> 7 k -> 7 v -> 7 k -> 7 v -> 7 k -> 4 v -> 4 k -> 7 v -> 7 k -> 7 v -> 7 k -> 7 v -> 7 k -> 7 v -> 7 k -> 7 v -> 7 k -> 7 v -> 7
可以看到 go閉包裡頭併發的使用外部自由變數後,輸出的結果出乎意料是錯亂的,
這說明這種情形,應該是用傳參的方式,而非引用外部變數
修改方法兩種:
1.傳參
m := make(map[int]int, 10)
for i := 1; i<= 10; i++ {
m[i] = i
}
for k, v := range(m) {
go func(k, v int) {
fmt.Println("k ->", k, "v ->", v)
}(k, v)
}
2.序列執行
m := make(map[int]int, 10) for i := 1; i<= 10; i++ { m[i] = i } for k, v := range(m) { func() { fmt.Println("k ->", k, "v ->", v) }() }
go run tmp.go
k -> 1 v -> 1
k -> 6 v -> 6
k -> 10 v -> 10
k -> 2 v -> 2
k -> 3 v -> 3
k -> 4 v -> 4
k -> 5 v -> 5
k -> 7 v -> 7
k -> 8 v -> 8
k -> 9 v -> 9
最近準備溫習一下golang,空了會更新下學習協程,gc,常用引用底層實現相關的內容,感興趣可以關注下我哦~
作者 —— 靑い空゛出處:
除特別註明外,本站所有文章均為靑い空゛原創,歡迎轉載分享,但請註明出處。