В PHP 8 появилось новое выражение match . Это мощная фича, которая часто будет более удачным выбором, чем использование switch . Так в чем же именно разница?
Давайте начнем со сравнения. Вот классический пример с switch :
switch ($statusCode) {
case 200:
case 300:
$message = null;
break;
case 400:
$message = 'not found';
break;
case 500:
$message = 'server error';
break;
default:
$message = 'unknown status code';
break;
}А вот его эквивалент с match :
$message = match ($statusCode) {
200, 300 => null,
400 => 'not found',
500 => 'server error',
default => 'unknown status code',
};Прежде всего, выражение match значительно короче:
- оно не требует оператора break
- оно позволяет объединять различные ветви в одну через запятую
- оно возвращает значение, поэтому присваивание нужно делать только один раз
Это уже немало, но есть и другие преимущества!
Без приведения типов
match выполняет строгое сравнение типов вместо нестрогого. Это аналогично использованию === вместо == . Возможно, мнения о том, хорошо это или плохо, разойдутся, но это отдельная тема для разговора.
$statusCode = '200';
$message = match ($statusCode) {
200 => null,
default => 'unknown status code',
};
// $message = 'unknown status code'Неизвестные значения вызывают ошибки
Если вы забыли обработать какое-то значение и при этом не указали ветку default , PHP выбросит исключение UnhandledMatchError . Опять же, больше строгости, но это предотвратит появление незамеченных багов.
$statusCode = 400;
$message = match ($statusCode) {
200 => 'perfect',
};
// UnhandledMatchErrorПока только однострочные выражения
Как и в случае с короткими замыканиями, вы можете написать только одно выражение. Блоки выражений, вероятно, будут добавлены в будущем, но пока неясно, когда именно.
Объединение условий
Вы уже заметили отсутствие break ? Это также означает, что match не поддерживает сквозное выполнение (fallthrough), как две объединенные строки case в первом примере с switch . С другой стороны, вы можете объединять условия в одной строке, разделяя их запятыми.
Таким образом, вы получаете ту же функциональность, что и у switch, но с меньшим количеством кода и меньшей вероятностью ошибиться. Сплошные плюсы!
$message = match ($statusCode) {
200, 300, 301, 302 => 'combined expressions',
};Сложные условия и производительность
Во время обсуждения RFC некоторые разработчики предлагали следующий паттерн в качестве аргумента против добавления выражения match :
$message = [
$this->matchesRegex($line) => 'match A',
$this->matchesOtherRegex($line) => 'match B',
][$line] ?? 'no match';Однако здесь есть один важный нюанс: при таком подходе сначала будут выполнены все функции регулярных выражений, что снизит производительность. Отличный аргумент в пользу match .
Выбрасывание исключений
Наконец, благодаря выражениям throw в PHP 8, при желании вы можете выбрасывать исключения прямо из ветви выражения.
$message = match ($statusCode) {
200 => null,
500 => throw new ServerError(),
default => 'unknown status code',
};Сопоставление с шаблоном (Pattern matching)
И еще кое-что: сопоставление с шаблоном. Это техника, используемая в других языках программирования, которая позволяет выполнять более сложное сопоставление, чем просто сравнение со значениями. Представьте себе это как регулярные выражения, но для переменных, а не для текста.
На данный момент сопоставление с шаблоном не поддерживается, так как это довольно сложная фича, но Илиja Товило, автор RFC, упомянул ее как возможную будущую возможность. Будем ждать!
Посмотрите мое последнее видео: DX matters
Итак, switch или match?
Если бы мне нужно было описать выражение match одним предложением, я бы сказал, что это более строгая и современная версия его младшего брата switch .
Есть случаи, когда switch предлагает больше гибкости, особенно с многострочными блоками кода. Тем не менее, строгость оператора match подкупает, а перспектива появления сопоставления с шаблоном может кардинально изменить PHP.
Признаюсь, за последние годы я практически не писал конструкций switch из-за их многочисленных причуд — причуд, которые match успешно решает. И хотя он еще не идеален, я могу представить множество юзкейсов, где match будет отличным выбором.
А каково ваше мнение?
Комментарии (0)
Пока нет комментариев — будьте первым.