在 for 迴圈中呼叫 defer - 是否有更好的方法來延遲從通道讀取回應?這是許多開發者在使用 Go 語言時常遇到的問題。 defer 關鍵字在 Go 語言中用於延遲執行函數,在 for 迴圈中使用 defer 可以確保每次迴圈結束後都會執行某些操作。然而,如果需要在每次循環中從通道讀取回應,使用 defer 可能並不是最佳的選擇。那麼,是否有更好的方法來延遲從通道讀取回應?讓我們一起來探討一下。
我正在嘗試呼叫一個在循環中傳回通道的函數。然後將該通道附加到切片 channelslice
上。最後,迭代通道切片並列印每個通道的響應。當我這樣做時,我的 ide 顯示警告:
possible resource leak, 'defer' is called in the 'for' loop
如您所見,我在第二個 for 迴圈內呼叫 close(channelslice[i])
。這是不推薦的嗎?另外,這怎麼會導致資源外洩呢?有沒有更好的方法來處理關閉或切片通道?
package main import ( "fmt" "math/rand" ) func t() chan int { c := make(chan int) go func() { c <- rand.Intn(100) }() return c } func main() { channelSlice := make([]chan int, 0) for i := 0; i<100; i++ { // Keep making concurrent calls // Will read responses from the channel later channelSlice = append(channelSlice, t()) } for i := 0; i<100; i++ { defer close(channelSlice[i]) // Warning thrown by IDE fmt.Println(<-channelSlice[i]) } }
如@mkopriva指出的,
延遲呼叫在周圍函數退出時執行,當周圍非功能塊退出時不會呼叫它們。將循環體封裝在閉包中。
這是我所做的:
for i := 0; i<100; i++ { func() { defer close(channelSlice[i]) fmt.Println(<-channelSlice[i]) }() }
如您所見,我將 defer
語句包裝在 iife(立即呼叫函數表達式)中。讓它成為一個閉包也很好。
這確保了通道現在將關閉並且不會出現記憶體洩漏。
以上是在 for 迴圈中呼叫 defer - 是否有更好的方法來延遲從通道讀取回應?的詳細內容。更多資訊請關注PHP中文網其他相關文章!