WaitGroups 參考中的指標或變數
在sync 套件中,WaitGroups 的Add、Done 和Wait 函數都是由指向的Wc指針。但是,以下程式碼似乎與此約定相矛盾:
package main import ( "fmt" "sync" "time" ) func worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d starting\n", id) time.Sleep(time.Second) fmt.Printf("Worker %d done\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() }
在此程式碼中,雖然使用指標變數呼叫 Done,但使用變數(而不是指標)呼叫 Add 和 Wait。
解釋:
儘管變數宣告為 var wgsync.WaitGroup,但 Add, Done 和 Wait 函數透過其指標接收器 (*WaitGroup) 存取。 wg 的值被 Go 編譯器隱式轉換為指標。這是必要的,因為這些方法被定義為指標接收器,如函數宣告中所示:
Add -------> func (wg *WaitGroup) Add(delta int) Done ------> func (wg *WaitGroup) Done() Wait ------> func (wg *WaitGroup) Wait()
當將非指標值傳遞給指標接收器方法時,編譯器會自動取得其地址(指針到值)。因此,即使 wg 被宣告為變量,所有三個函數仍然在指向 wg 的指標上呼叫。
使用指標接收器的主要原因是避免不必要的資料複製。透過傳遞指針,函數可以直接修改底層的 WaitGroup,而不是複製它。這提高了效能,特別是對於頻繁修改的 WaitGroups。
在提供的程式碼中,將wg 的位址傳遞給工作人員至關重要,因為如果它作為值傳遞(不帶&),則中的Done 函數每個工作執行緒都會引用與主函數中的Add 和Wait 不同的指標。這會導致不正確的行為。
以上是為什麼即使宣告為變量,也要使用指標呼叫 WaitGroup 的 Add、Done 和 Wait 函數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!