Ответ
Разница в управлении счетчиком ожидания WaitGroup.
В цикле:
var wg sync.WaitGroup
for _, task := range tasks {
wg.Add(1) // Увеличиваем счетчик перед запуском каждой горутины
go func(t Task) {
defer wg.Done()
process(t)
}(task)
}
wg.Wait()
Плюсы:
- Точно отражает количество запущенных горутин.
- Безопасно, если количество задач неизвестно заранее.
За циклом:
var wg sync.WaitGroup
wg.Add(len(tasks)) // Увеличиваем счетчик один раз
for _, task := range tasks {
go func(t Task) {
defer wg.Done()
process(t)
}(task)
}
wg.Wait()
Плюсы:
- Меньше накладных расходов (однократный вызов
Add). - Подходит, если количество задач известно и фиксировано.
Опасность: Если len(tasks) изменится после Add, счетчик может стать некорректным.