Стрелочные функции
Стрелочные функции появились в PHP 7.4 как
лаконичный синтаксис для анонимных функций.
И анонимные, и стрелочные функции реализованы
через класс Closure.
Основной вид записи стрелочных функций:
fn (argument_list) => expr
.
Стрелочные функции работают так же,
как анонимные функции,
за исключением того, что доступ к переменным
родительской области выполняется автоматически.
Когда стрелочная функция использует переменную,
которую определили в родительской области,
переменная неявно захватывается по значению.
В следующем примере функции $fn1 и
$fn2 ведут себя одинаково.
Пример #1 Стрелочные функции захватывают переменные по значению автоматически
<?php
$y = 1;
$fn1 = fn($x) => $x + $y;
// эквивалентно использованию $y по значению:
$fn2 = function ($x) use ($y) {
return $x + $y;
};
var_export($fn1(3));
?>
Результат выполнения приведённого примера:
Это также работает во вложенных стрелочных функциях:
Пример #2 Стрелочные функции захватывают переменные по значению автоматически, даже когда они вложены
<?php
$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Выведет 51
var_export($fn(5)(10));
?>
Подобно анонимным функциям,
синтаксис стрелочных функций допускает произвольные сигнатуры функций,
включая типы параметров и возвращаемых значений, значения по умолчанию, переменные,
а также передачу и возврат по ссылке.
Ниже приведены корректные примеры стрелочных функций:
Пример #3 Примеры использования стрелочных функций
<?php
fn(array $x) => $x;
static fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;
?>
Стрелочные функции используют привязку переменных по значению.
Это примерно эквивалентно выполнению use($x)
для каждой
переменной $x, используемой внутри стрелочной функции.
Привязка по значению означает, что невозможно изменить какие-либо значения
из внешней области.
Вместо этого можно использовать анонимные функции
для привязок по ссылкам.
Пример #4 Стрелочные функции не умеют изменять значения из внешней области видимости
<?php
$x = 1;
$fn = fn() => $x++; // Ничего не изменит
$fn();
var_export($x); // Выведет 1
?>