Closure
В этом примере на Go демонстрируется замыкание (closure) — функция, которая запоминает окружение, в котором она была создана.
1. Функция intSeq() создаёт замыкание
func intSeq() func() int {
i := 0 // Локальная переменная внутри intSeq
return func() int { // Возвращаемая анонимная функция
i++ // Замыкание "видит" переменную i
return i
}
}
i := 0— это локальная переменная внутриintSeq.- Возвращаемая функция
func() int“замыкается” вокругi, то есть запоминает её и может изменять.
2. Создаём экземпляр замыкания
nextInt := intSeq() // Переменная nextInt теперь — функция
- При вызове
intSeq():- Создаётся переменная
i = 0. - Возвращается функция-замыкание, которая удерживает ссылку на
i.
- Создаётся переменная
3. Вызов nextInt() изменяет состояние i
p(nextInt()) // Выведет: === 1 ===
p(nextInt()) // Выведет: === 2 ===
p(nextInt()) // Выведет: === 3 ===
- Каждый вызов
nextInt():- Увеличивает
iна 1 (i++). - Возвращает новое значение.
- Увеличивает
iсохраняется между вызовами — это и есть “запомненное окружение”.
4. Новое замыкание — новый экземпляр i
newInts := intSeq() // Создаётся новый экземпляр замыкания
p(newInts()) // Выведет: === 1 === (не 4!)
newInts— это новое замыкание с собственной переменнойi = 0.- Оно не связано с
nextInt— их состояния (i) независимы.
Итог: как работает замыкание
- Запоминает окружение (переменные, например
i), даже после выхода из внешней функции. - Сохраняет состояние между вызовами (
iувеличивается). - Каждое новое замыкание создаёт свой экземпляр переменных.
Это полезно для:
- Генераторов (как в примере).
- Callback-функций с сохранением состояния.
- Инкапсуляции данных (аналог private переменных в ООП).
Пример в JavaScript (для сравнения):
function intSeq() {
let i = 0;
return () => ++i;
}
Работает аналогично!