Go: Функции
Теория: Анонимные функции
В языке Go функции можно объявлять не только с именем, но и без него. Такие функции называются анонимными. Они позволяют определять логику «на месте», без необходимости придумывать отдельное имя и выносить её в общий список функций. Это удобно в ситуациях, когда функция нужна только внутри ограниченного контекста — например, при работе с обработчиками событий, сортировкой, запуском горутин.
Представим: у нас есть программа, где надо один раз что-то посчитать. Создавать отдельную именованную функцию ради одной строчки — избыточно. В таких случаях анонимные функции помогают сделать код компактнее и читаемее.
Определение и вызов анонимной функции
Анонимная функция в Go объявляется так же, как и обычная, но без имени:
Здесь func(a, b int) int { return a + b } — это функция без имени. Мы сразу передали ей аргументы (3, 5) и получили результат.
Сохранение анонимной функции в переменную
Иногда удобнее сохранить функцию в переменной и использовать её несколько раз:
Здесь multiply ведёт себя как обычная именованная функция, только её мы объявили внутри main.
Замыкания: доступ к внешним переменным
Анонимные функции могут обращаться к переменным, определённым снаружи. Это называется замыканием. Оно позволяет «захватывать» контекст, в котором функция создана.
Здесь increment «помнит» переменную counter, даже после первого вызова. Это делает анонимные функции удобными для создания функций-счётчиков, генераторов или обёрток.
Анонимные функции и горутины
Часто анонимные функции используют вместе с горутинами, когда нужно запустить задачу параллельно:
Мы не создавали отдельную функцию, а сразу передали анонимную в go.
Анонимные функции как аргументы других функций
Go активно применяет передачу функций как параметров. Благодаря анонимным функциям это можно делать прямо «на месте»:
Мы написали правило сортировки прямо в месте вызова sort.Slice, без создания отдельной функции.
Передача анонимных функций в другие функции
Go активно использует функции как параметры. Когда мы передаём анонимную функцию прямо «на месте», код остаётся компактным и читаемым.
Пример со стандартной библиотекой strings.Map, которая применяет функцию ко всем символам строки:
Здесь мы описали логику прямо в месте вызова strings.Map. Если бы мы вынесли её в отдельную функцию, код стал бы длиннее и менее наглядным.
Возвращение анонимных функций (фабрики)
Функции могут возвращать другие функции. Если возвращаемая функция замыкает внешние переменные, мы получаем генератор поведения.
Пример: фабрика инкрементаторов.
Каждый вызов newCounter создаёт своё замыкание с собственным count. В реальной жизни это часто используют для генерации идентификаторов, лимитеров и конфигурируемых обработчиков.
Анонимные функции внутри циклов и подводные камни
Очень часто разработчики запускают горутины внутри цикла. Но анонимные функции здесь могут привести к багу: они «захватывают» переменную цикла, а не её копию.
Что выведется? Почти всегда три раза «Горутина: 4». Почему? Потому что все три анонимные функции замкнули одну и ту же переменную i, и к моменту выполнения горутин цикл уже завершился.
Как правильно:
Теперь в замыкание передаётся копия i, и результат будет корректным: 1, 2, 3.
HTTP-обработчики
В веб-разработке на Go анонимные функции встречаются постоянно. В пакете net/http почти всегда используется именно этот подход:
Мы передали анонимные функции прямо в HandleFunc, и каждая из них знает, что делать с запросом. Такой приём позволяет держать логику рядом с маршрутизацией.
Отложенные вызовы (defer)
Анонимные функции удобны, когда нужно выполнить какой-то блок кода при выходе из функции.
Здесь defer гарантирует выполнение анонимной функции в самом конце работы main. Это хороший приём для освобождения ресурсов, закрытия файлов и соединений.
Выводы
Анонимные функции в Go позволяют писать компактный код, когда функция нужна только в ограниченном контексте. Они удобны для одноразовых вычислений, передачи функций как аргументов, работы с горутинами и создания замыканий. Главная их сила — доступ к внешнему окружению и возможность держать логику «рядом с использованием».


