Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpGrLv 153 of 280 menu
◀ ▶

Переменная цикла и горутина в Go

Переменная цикла своя на каждом шаге, и горутина берет именно это значение. С версии 1.22 старый сбой, когда все ветки видели одно последнее число, больше не возникает: каждая итерация создает отдельное имя для тела цикла.

При запуске из цикла в ветку передают текущий номер шага или копируют его в локальную переменную внутри анонимной функции. После исправления языка достаточно захватить переменную цикла напрямую.

Запустим три ветки с разными номерами:

package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup wg.Add(3) for i := 1; i <= 3; i++ { go func() { defer wg.Done() fmt.Println(i) }() } wg.Wait() }

На экране по очереди 1, 2 и 3, хотя порядок строк может меняться. Каждая ветка читает свой i, а не общее последнее значение.

Тот же смысл с явной передачей параметра в анонимную функцию:

package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup wg.Add(2) for k := 10; k <= 11; k++ { go func(v int) { defer wg.Done() fmt.Println(v) }(k) } wg.Wait() }

Дан следующий код:

for n := 0; n < 2; n++ { go func() { fmt.Println(n) }() }

Скажите, какие значения n могут напечатать ветки в Go 1.27.

Дан цикл:

for i := 1; i <= 3; i++ { go report(i) }

Скажите, сколько разных чисел выведет report, если она печатает аргумент.

Скажите, чем опасен был старый захват одного имени цикла всеми ветками до исправления в 1.22.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить