PHP: Функции
Теория: Замыкание
Каждая функция в своем теле задает так называемую область видимости. Внутри этой области доступны только те переменные, которые были определены там же. Определенные вне функции переменные невидимы внутри нее:
Этот код выдаст предупреждение PHP Notice: Undefined variable: age. Переменная $age определена вне контекста функции и невидима внутри. Точно такое же поведение и у анонимных функций:
Но передача аргументов все же возможна, и делается она благодаря замыканию. С помощью этого механизма можно захватить переменные из внешнего окружения и использовать их внутри. Правда, это работает только для анонимных функций. Замыканием нередко называют и саму функцию, которая осуществила захват внешних переменных:
Захват переменных осуществляется с помощью ключевого слова use и списка переменных, который идет после этого слова. Крайне важно осознать, что use используется при определении функции, а не ее вызове.
Может возникнуть закономерный вопрос: «Зачем это делать, если переменные можно передать в сам вызов?». Попробуем разобраться:
Замыкания полезны, когда функция определяется в одном месте, а используется в совершенно другом. Замыкание позволяет не таскать за собой гору переменных, а в некоторых ситуациях без него просто не обойтись.
Вспомните функцию without() из пакета Funct. Она принимает на вход массив и значение, а возвращает новый массив, полученный фильтрацией старого по переданному значению. Его реализация построена на функциях высшего порядка и подразумевает фильтрацию. Сложность возникает при описании предиката, ведь внутри анонимной функции нужно сравнивать текущее значение и переданный элемент. Замыкание позволяет решить эту задачу просто:
Без добавления use ($value) ничего не получится, потому что $value не виден внутри анонимной функции.
В замыкание можно передать данные по ссылке, что позволит их менять внутри. Но делать так никогда не стоит. Подобное использование создает невероятно сложный в отладке и сопровождении код. Единственная причина, по которой можно использовать передачу по ссылке - рекурсия внутри анонимной функции. Подробнее об этом в другом курсе.
Стрелочные функции
Главная цель введения стрелочных функций — это создание более лаконичного кода. Поэтому кроме сокращенного синтаксиса, они получили автоматический захват внешних переменных. Другими словами, при использовании стрелочных функций нам не нужен use:
.png)
