Вопрос проверяет понимание безопасного использования sync.WaitGroup в горутинах и правил передачи указателей в Go.
В Go sync.WaitGroup используется для ожидания завершения группы горутин. Обычно WaitGroup передается в горутину по указателю, чтобы все горутины работали с одним экземпляром счетчика. Внутри горутины не требуется явно разыменовывать указатель — достаточно вызвать метод Done() через указатель, и компилятор автоматически разыменует его.
package main
import (
"fmt"
"sync"
)
func worker(wg *sync.WaitGroup, id int) {
defer wg.Done() // безопасно, компилятор разыменует указатель
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1)
go worker(&wg, i)
}
wg.Wait()
fmt.Println("All workers finished")
}Методы WaitGroup (Add, Done, Wait) объявлены с получателем-указателем, поэтому при вызове через указатель Go автоматически разыменовывает его. Попытка явного разыменования, например (*wg).Done(), избыточна и может запутать код. Главное — передавать указатель, а не копию, чтобы избежать race condition.
Используйте передачу указателя на sync.WaitGroup в горутины и вызывайте wg.Done() через defer. Это гарантирует корректную синхронизацию без лишних операций разыменования.