В PHP 7.4 войдут стрелочные функции (сокращенная запись анонимных функций)

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Голосование по сокращенному синтаксису для функций завершено (51 "за", 8 "против").


Было:


$result = array_filter($paths,  function ($v) use ($names) {
    return in_array($v, $names);
});

Стало:


$result = array_filter($paths,  fn($v) => in_array($v, $names));

Подробности под катом


Новый синтаксис такой:


Синтаксис


fn(список_параметров) => возвращаемое_выражение

В сигнатуре стрелочной функции, как и в обычной функции, можно указывать типы, дефолты и прочее


fn(array $x) => $x;
fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

Внимание! Появилось новое ключевое слово fn, а это означает обратную несовместимость!


Другие (отброшенные) идеи по синтаксису


Рассматривались варианты:


 // невозможно реализовать, путаница с элементами массивов в некоторых случаях
($x) => $x * $y

// так можно сделать, но слишком много фигурных скобок, особенно для вложенных функций
{ ($x) => $x + $y } 

// так сделано в языке Hack; но слишком сложно для текущего парсера 
($x) ==> $x * $y

// нереализуемо, путаница с получением свойств объекта 
($x) -> $x * $y

// сейчас парсер это понимает как $x--  > $x*$y  
$x --> $x * $y 

// так сделано в Rust, но читабельность спорна
|$x| => $x * $y 

и некоторые другие


Замыкание переменных


Важно! В отличие от предыдущих версий php, где надо было явно задавать замыкаемые переменные оператором use, стрелочная функция неявно замыкает на себе весь родительский скоуп.


Вот эквивалентные записи:


$y = 1;

$fn1 = fn($x) => $x + $y;

$fn2 = function ($x) use ($y) {
    return $x + $y;
};

Переменная $this замыкается точно также, как и любая другая переменная. Если это нежелательное поведение, можно его запретить ключевым словом static.


class Test {
    public function method() {
        $fn = fn() => var_dump($this);
        $fn(); // object(Test)#1 { ... }

        $fn = static fn() => var_dump($this);
        $fn(); // Error: Using $this when not in object context
    }
}

Замыкание переменных в стрелочных функциях происходит по значению (в отличие от языка Go, например). Т.е. изменение переменных внутри функции не приведет к изменению переменной в родительском скоупе.


Выводы


Код стал значительно компактнее, и хотя не такой компактный, как в javascript и некоторых других языках, но всё же писать будет значительно приятнее:


$result = Collection::from([1, 2])
    ->map(fn($v) => $v * 2)
    ->reduce(fn($tmp, $v) => $tmp + $v, 0);

echo $result; //6

В отличие от некоторых других языков стрелочные функции в php не поддерживают несколько statements, разделенных через символ ;, потому что это (по мнению авторов RFC) противоречит идее сокращенного синтаксиса. Возможно это будет пересмотрено в будущем.


Мы обязательно детально обсудим стрелочные функции в php в подкасте "Цинковый прод", так что не забудьте подписаться.


Ссылка на RFC: https://wiki.php.net/rfc/arrow_function

Источник: https://habr.com/ru/post/450544/


Интересные статьи

Интересные статьи

Хеш-функция - это такая функция, которая осуществляет преобразование набора входных данных произвольной длины в битовую последовательность установленной длины. Хеш-функци...
Эту статью написал еще пару лет назад, и не знал куда ее можно было бы выложить, а потом и забыл. Смысл использования языка С при разработке расширений для PostgreSQL по сравнению с интерпрети...
В прошлой статье мы описали эксперимент по определению минимального объема вручную размеченных срезов для обучения нейронной сети на данных сейсморазведки. Сегодня мы продолжаем эту тему, выбирая...
Несмотря на то, что “в коробке” с Битриксом уже идут модули как для SOAP (модуль “Веб сервисы” в редакции “Бизнес” и старше), так и для REST (модуль “Rest API” во всех редакциях, начиная с...
LGR (Lazy Game Reviews) — один из крупнейших англоязычных каналов, посвященных старому компьютерному железу и не менее старым играм. В конце 2018 года он выпустил видео с рассказом о том, как он ...