3 回答

TA貢獻1829條經驗 獲得超13個贊
您的函數文字i從外部范圍引用。如果您請求 的值i,您將獲得當前的任何值i。為了使用iGo 例程創建時的值,請提供一個參數:
func main() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(i int) {
fmt.Println(i)
wg.Done()
}(i)
}
wg.Wait()
}

TA貢獻1810條經驗 獲得超4個贊
該變量i未在函數字面量中聲明,因此它成為閉包的一部分。理解閉包的一個簡單方法是考慮如何實現它們。簡單的解決方案是使用指針。你可以認為函數字面量被編譯器改寫成一些
func f123(i *int) {
fmt.Println(*i)
wg.Done
}
在調用此函數時,通過 go 語句,將
i
變量的地址傳遞給被調用的 f123(編譯器生成的示例名稱)。您可能正在使用默認的 GOMAXPROCS==1,因此 for 循環在沒有任何調度的情況下執行 5 次,因為該循環沒有 I/O 或其他“調度點”,例如通道操作。
當循環以 結束時
i == 5
,wg.Wait
finally 會觸發五個準備運行的 goroutines(對于 f123)的執行。他們當然都有指向同一個整數變量的相同指針i
。現在每個 goroutine 都看到相同的
i
值 5。
當 GOMAXPROCS > 1 運行時,或者當循環產生控制時,您可能會得到不同的輸出。這也可以通過例如runtime.Gosched來完成。
- 3 回答
- 0 關注
- 222 瀏覽
添加回答
舉報