Pattern matching — один из важнейших языковых механизмов в Rust, пришедший из функциональных языков. Он позволяет декларативно, лаконично и безопасно разбирать сложные варианты значений, в том числе с помощью дополнительных условий (guard-выражений), что даёт гибкость и контроль над логикой.
Без exhaustiveness checking (проверка исчерпывающего рассмотрения всех вариантов) часть сценариев мощности pattern matching может быть реализована с ошибками. Кроме того, без понимания порядка веток и guard-выражений можно ошибиться либо в логике, либо в производительности.
В Rust компилятор проверяет, что все варианты enum (или более простых pattern-структур) разобраны, либо есть ветка _. Ветка может быть дополнительно ограничена guard-выражением (if после pattern), и только при выполнении условия она "срабатывает". Оставшиеся варианты — не захватываются. Порядок веток важен: они проверяются сверху вниз.
Пример кода:
enum Message { Hello, Data(i32), Quit, } fn handle(msg: Message) -> &'static str { match msg { Data(n) if n > 10 => "Big Data", Data(_) => "Some Data", Hello => "Greet!", Quit => "Bye", } }
Ключевые особенности:
Срабатывает ли ветка с guard, если pattern совпал, но условие не выполняется?
Нет, в таком случае проверка идёт к следующей подходящей ветке. Pattern + guard — это атомарный "фильтр"; только когда оба совпали, выполняется тело ветки.
Влияет ли порядок веток в match на производительность?
Да. Особенно при обилии похожих паттернов с guard: компилятор проверяет ветки сверху вниз, что влияет на скорость проверки в рантайме — встречаемые чаще значения стоит обрабатывать раньше.
Можно ли опустить exhaustiveness checking, поставив только ветку _?
Технически да — это допустимо, но теряется надёжность: если тип исключит (или добавит) new элементы, компилятор не предупредит о нерассмотренном случае. Лучше всегда явно обрабатывать важные, а "_" — только в крайнем случае.
Код match для enum с guard-выражениями, где паттерн с guard идёт последним, но большинство значений проходит напрямую по ранней ветке _, и никогда не доходит до нужной обработке.
Плюсы:
_.Минусы:
Сначала перечисляются наиболее частые и важные варианты (с guard), затем exhaustively покрываются остальные — без лишнего кода в "_".
Плюсы:
Минусы: