在 Go 中編寫並發程式碼時,了解匿名函數的行為非常重要。在此範例中,我們探討了 for 迴圈和匿名函數產生意外輸出的場景。
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func() { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }() } wg.Wait() }
執行此程式碼令人驚訝地輸出「6, 6, 6, 6, 6」而不是預期的序列「2, 4, 1, 5, 3”。這是因為在 goroutine 啟動後,for 迴圈會繼續更新變數 i。
上面程式碼中的匿名函數是一個閉包。閉包捕獲創建函數體時使用的變數。在這種情況下,變數 i 在 Goroutine 啟動時被捕獲。然而,goroutine 啟動後,循環會繼續更新 i。
由於循環直到 i 大於 5 才會終止,所以 goroutine 最終執行時 i 為 6。因此,每個 goroutine 都會列印閉包中捕獲的 i 值,在本例中為 6。只有當變數 i 作為參數傳遞給匿名函數時,才會觀察到預期的輸出,從而在呼叫時有效地建立該值的副本。
以上是為什麼我的 Go 並發範例列印'6,6,6,6,6”而不是預期的順序?的詳細內容。更多資訊請關注PHP中文網其他相關文章!