Pull to refresh

Стрелочные функции в PHP 7.4

Reading time2 min
Views25K
Original author: Brent


Стрелочные функции, также называемые короткими замыканиями (short closures), станут хорошим способом писать чистый код в PHP. Такая форма записи будет полезной при передаче замыканий в такие функции как array_map или array_filter.


Пример:


// Коллекция объектов Post
$posts = [/* … */];

$ids = array_map(fn($post) => $post->id, $posts);

Раньше нужно было писать так:


$ids = array_map(function ($post) {
    return $post->id;
}, $posts);

Кратко:


  • Доступны с PHP 7.4
  • Начинаются с ключевого слова fn
  • Могут иметь только одно выражение, также являющееся возвращаемым значением
  • Не поддерживается return
  • Type-hintihg поддерживается в аргументах и возвращаемых значениях

Строготипизированный способ написания примера выше:


$ids = array_map(fn(Post $post): int => $post->id, $posts);

Еще две важные вещи:


  • Поддерживается оператор переменного значения
  • Поддерживаются ссылки, как для аргументов, так и для возвращаемых значений

Если вы хотите вернуть значение по ссылке, используйте следующий синтаксис:


fn&($x) => $x

Стрелочные функции реализуют ту же функциональность, которую вы ожидаете от нормальных замыканий, только содержат в себе одно выражение.


Нет многострочности


Вы верно прочитали: короткие замыкания могут содержать только одно выражение. Это означает что вы не можете иметь несколько строк в них.


Аргументация такова: целью коротких замыканий является снижение многословности. fn, однозначно короче чем function во всех смыслах. Пропуск ключевых слов function и return ничего не меняет, но позволяет сделать код более читаемым.


Согласны ли вы с этим мнением? В то же время при наличии нового синтаксиса для однострочных функций, существует множество многострочных, которым тоже бы не помешал подобный апгрейд.


Надеюсь, в будущем, появится RFC с коротким объявлениим и многострочных функций, но пока это только мои мечты.


Переменные из внешней области видимости


Еще одним существенным различием между короткими и нормальными замыканиями является то, что первые не требуют использования ключевого слова use для получения доступа к данным из внешней области видимости.


$modifier = 5;

array_map(fn($x) => $x * $modifier, $numbers);

Важно отметить, что вы не можете изменять эти переменные. Значения связаны по значению, а не по ссылке. Это означает, что вы можете изменять $modifier внутри короткого замыкания, но это не повлияет на переменную $modifier находящуюся вне.


Единственное исключение — ключевое слово $this, которое будет работать точно также, как и в нормальном варианте:


array_map(fn($x) => $x * $this->modifier, $numbers);

Будущие возможности


Я уже упоминал идею с многострочными короткими замыканиями выше. Еще одно полезное предложение — позволить использовать короткий синтаксис в классах, например для геттеров и сеттеров:


class Post {
    private $title;

    fn getTitle() => $this->title;
}

В целом, стрелочные функции это очень хорошая фича, хотя есть еще область для улучшения.


Есть ли у вас какие-либо мысли по этому поводу?

Tags:
Hubs:
Total votes 23: ↑22 and ↓1+21
Comments20

Articles