TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7264 3.11K
✏️ Переменная цикла своя на каждой итерации

В Go переменная цикла for ... range создаётся заново на каждой итерации. Это снимает одну из самых частых проблем при работе с горутинами и замыканиями, когда несколько функций случайно ссылаются на одно и то же значение. Разберём как этим пользоваться.

Замыкание захватывает не значение переменной, а саму переменную. Если бы v была одна на весь цикл, все запущенные горутины ссылались бы на общую ячейку и видели бы её последнее значение.

Поскольку в Go у каждой итерации своя v, такого не происходит:
for _, v := range data {
go func() { fmt.Println(v) }()
}

Каждая горутина печатает значение своей итерации, а не последний элемент data. Никаких обходных приёмов внутри тела цикла для этого не нужно.

На каждом проходе компилятор заводит новую переменную и копирует в неё текущее значение. Замыкание, которое вы создаёте внутри тела, привязывается именно к этой копии. Когда итерация заканчивается, её переменная остаётся жить ровно столько, сколько на неё ссылаются запущенные функции.

То же касается и индекса в форме с двумя переменными:
for i, v := range items {
go func() {
fmt.Println(i, v)
}()
}


И i, и v уникальны для каждого прохода, поэтому пара значений всегда соответствует своей итерации.

Поведение привязано к версии языка в директиве go файла go.mod. Оно действует, когда там указано go 1.22 или выше. Если в модуле прописана версия старше, тот же код соберётся со старой семантикой даже на новом компиляторе. Так одна и та же кодовая база ведёт себя предсказуемо, а апгрейд тулчейна не меняет логику молча.

ℹ️ О чём помнить

Копия создаётся под каждую итерацию, но это именно копия значения. Если в v лежит срез или указатель, копируется он, а не данные за ним, и общий доступ к этим данным из горутин по-прежнему требует синхронизации. Свойство решает проблему захвата переменной, а не гонок по самим данным.

Опираться на это можно в любом коде, где замыкания и горутины создаются внутри for ... range. Значение каждой итерации остаётся при ней, и писать переобъявление внутри тела больше не требуется.

📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max

🐸 Библиотека Go-разработчика

#GoDeep
  • ❤ 5
  • 👍 2
More from @goproglib
  1. Sep 28, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — 1 true / 0 false 🔥 — 1 true /…
  2. Sep 28, 2026👩‍💻 Что на самом деле происходит внутри Go map? После Go 1.24 обычный map внутри работае…
  3. Sep 26, 2026🔥 В Go 1.27 появился portable SIMD До этого SIMD-оптимизации в Go требовали архитектурног…
  4. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
  5. Sep 25, 2026💡 Код работает. А data race уже есть В Go можно записать значение в одной горутине, прочи…
  6. Sep 23, 2026💥 TCP/IP: что происходит с данными в сети Когда Go-приложение отправляет данные по сети,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →