Ответ
Да, это классический пример замыкания (closure).
Замыкание — это функция, которая «запоминает» лексическое окружение (scope), в котором она была создана. Она имеет доступ к переменным из своей внешней (охватывающей) области видимости, даже после того, как внешняя функция завершила свою работу.
Как это работает:
Функция-замыкание не просто копирует значение переменной, а получает на неё ссылку. Это позволяет не только читать, но и изменять её состояние.
Пример 1: Простой доступ
package main
import "fmt"
func main() {
message := "Это секрет"
// Эта анонимная функция является замыканием.
// Она "захватывает" переменную message из окружения main.
printSecret := func() {
fmt.Println(message)
}
printSecret() // Выведет: Это секрет
}
Пример 2: Изменение состояния (классический пример счётчика)
Этот пример наглядно показывает, что замыкание работает с состоянием, а не с копией.
package main
import "fmt"
// newCounter возвращает функцию-замыкание.
// Каждый вызов newCounter создает свой собственный экземпляр `count`.
func newCounter() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
counterA := newCounter()
fmt.Println(counterA()) // Выведет: 1
fmt.Println(counterA()) // Выведет: 2
// Создадим другой, независимый счётчик
counterB := newCounter()
fmt.Println(counterB()) // Выведет: 1
}
Важное уточнение:
Не стоит путать замыкания с видимостью на уровне пакета (неэкспортируемые переменные, начинающиеся с маленькой буквы). Замыкание — это механизм, связанный с лексической областью видимости функций, а экспорт/импорт — с видимостью между пакетами.