match式はswitchの上位互換なのか

match式はPHP 8で追加された分岐構文です。厳密比較・値を返す・網羅漏れで例外という特徴を持ち、switchの事故りやすい部分を避けられる書き方です。

PHP 8で入ったmatch式、switchの見た目違いくらいに思っている人が多い気がします。実際は挙動がいくつか違っていて、switchのハマりどころを回避できるようになっています。

厳密比較である

switchは緩やかな比較(==)ですが、matchは厳密比較(===)です。これが地味に効きます。

$x = '1';
switch ($x) {
    case 1: echo 'switchは数値1にマッチ'; break; // これが実行される
}
echo match($x) {
    1 => '数値1',
    '1' => '文字列1', // matchはこっち
};

switchの緩い比較で「文字列なのに数値のcaseに入ってしまう」バグ、経験ある人も多いはず。matchはそれが起きません。

breakいらず・値を返す

matchは式なので値を返します。breakの書き忘れによるフォールスルー事故がそもそも発生しません。

$label = match($status) {
    'draft' => '下書き',
    'publish', 'future' => '公開系',
    default => '不明',
};

カンマ区切りで複数条件をまとめられます。

マッチしないと例外

defaultが無くてどれにもマッチしないと、matchはUnhandledMatchErrorを投げます。switchのように「何も起きず素通り」しないので、想定外の値に気づけます。これは安全側に倒れていて良い挙動です。

まとめ

厳密比較・break不要・網羅漏れで例外。この3点で、matchはswitchの事故りやすい部分を潰しています。値を返す分岐ならmatchが基本、複数文を実行したいならswitch、という住み分けでいいと思います。

よくある質問

Q. matchでdefaultを書かないとどうなりますか。
A. どのケースにもマッチしないとUnhandledMatchErrorが投げられます。switchのように素通りしないので、想定外の値に気づけます。

Q. matchとswitchはどう使い分ければいいですか。
A. 値を返す分岐ならmatch、複数の文を実行したい処理ならswitch、という住み分けが素直だと思います。

類似投稿

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です