在 Go 中,傳遞參數的匿名函數的行為可能與閉包不同。本文深入探討了差異及其意義。
閉包範例:
func main() { done := make(chan bool, 1) go func() { time.Sleep(50 * time.Millisecond) done <- true }() <-done }
在此閉包中,匿名函數沒有參數,而是存取周圍範圍中存在的完成通道。
參數範例:
func main() { done := make(chan bool, 1) go func(c chan bool) { time.Sleep(50 * time.Millisecond) c <- true }(done) <-done }
在本例中,匿名函數接受一個參數 c,即通道,並直接與其互動。
何時使用參數
將參數傳遞給匿名函數主要適用於共享變數可能導致意外行為的場景。考慮以下範例:
for i := 0; i < 3; i++ { go func() { fmt.Println(i) }() // Closure }
這裡,匿名函數是一個閉包,也就是它引用 for 迴圈中定義的 i 變數。由於所有 goroutine 共享相同的 i 變量,因此它們將列印「3」(循環完成後 i 的最終值),即使我們可能期望它們會列印「0」、「1」和「2」。
為了修正這個問題,我們可以將i 作為參數傳遞:
for i := 0; i < 3; i++ { go func(v int) { fmt.Println(v) }(i) // Parameter }
現在,每個goroutine 在呼叫函數時都會收到i 變數的副本,從而導致在正確的輸出中:「0」、「1」和「2」。
結論
雖然閉包允許方便地訪問周圍範圍內的變量,在處理共享變量時,傳遞參數可以提供更多控制並確保可預測的行為,特別是在並發場景中。
以上是何時在 Go 匿名函數中使用參數與閉包?的詳細內容。更多資訊請關注PHP中文網其他相關文章!