Skip to content

Основы match

match — это наиболее мощная управляющая конструкция в YaoXiang. Она позволяет выбрать различные пути обработки в зависимости от формы (структуры) значения. Если вы использовали switch в других языках, то match представляет собой его значительно улучшенную версию.

Базовый синтаксис

Определение выражения match в грамматике:

match Expr { MatchArm+ }
MatchArm : Pattern ('|' Pattern)* ('if' Expr)? '=>' Expr ','

Разберём по частям:

  • после match указывается значение для сопоставления
  • в {} содержится одна или несколько ветвей сопоставления (MatchArm)
  • каждая ветвь: шаблон затем =>, затем выражение-результат
  • каждая ветвь завершается запятой

Простейший пример:

yaoxiang
number = 2

text = match number {
    0 => "ноль",
    1 => "один",
    2 => "два",
}
print(text)  // "два"

match как выражение

Подобно if, match также является выражением — оно вычисляет значение. Типы возвращаемых значений всех ветвей должны совпадать:

yaoxiang
score = 85

grade = match score {
    90..100 => "A",    // диапазон (продвинутая тема)
    80..89 => "B",
    70..79 => "C",
    60..69 => "D",
    _ => "F",          // подстановочный знак: все остальные случаи
}
print(grade)  // "B"

Примечание: диапазоны 90..100 и подобные — это продвинутая тема, которая подробно рассматривается в Продвинутое сопоставление с образцом. В этой главе мы сосредоточимся на базовых шаблонах.

Базовые шаблоны

Шаблон литерала

Сопоставление с конкретным значением:

yaoxiang
response = 404

message = match response {
    200 => "OK",
    301 => "Moved",
    404 => "Not Found",
    500 => "Server Error",
    _ => "Unknown",
}
print(message)  // "Not Found"

Идентификаторный шаблон

Использование имени переменной для захвата сопоставленного значения:

yaoxiang
result: Result(Int, String) = ok(42)

description = match result {
    ok(value) => "Успех, значение: " + value.to_string(),
    err(error) => "Ошибка, причина: " + error,
}
print(description)  // "Успех, значение: 42"

value в ok(value) — это идентификаторный шаблон, который захватывает фактическое значение, обёрнутое в ok. Вы можете использовать его в выражении после =>.

Подстановочный шаблон

_ — это подстановочный знак, который сопоставляется с любым значением. Обычно размещается последним, как兜底:

yaoxiang
command = "exit"

action = match command {
    "start" => "Запуск сервиса",
    "stop" => "Остановка сервиса",
    "restart" => "Перезапуск сервиса",
    _ => "Неизвестная команда: " + command,
}
print(action)  // "Неизвестная команда: exit"

Сопоставление должно быть исчерпывающим

match в YaoXiang требует покрытия всех возможных случаев — если компилятор обнаружит, что вы пропустили некоторые возможные значения, он выдаст ошибку. Это проявление безопасности match.

yaoxiang
// Этот код не скомпилируется
// value = true
// result = match value {
//     true => "Да",
//     // отсутствует ветвь false — ошибка компиляции!
// }

// Правильно — используем _ как резерв
value = true
result = match value {
    true => "Да",
    _ => "Нет",      // _ гарантирует обработку false
}

Когда вы точно знаете, что существует ограниченное количество вариантов (например, при сопоставлении с перечислением), компилятор помогает проверить, покрыт ли каждый вариант. Это мощный инструмент защиты от ошибок из-за пропущенных ветвей.

Комбинация нескольких шаблонов

Одна ветвь может сопоставляться с несколькими шаблонами, разделёнными |:

yaoxiang
day = "sunday"

type = match day {
    "monday" | "tuesday" | "wednesday" | "thursday" | "friday" => "Будний день",
    "saturday" | "sunday" => "Выходной",
    _ => "Недействительный",
}
print(type)  // "Выходной"

Ветви сопоставления выполняются по порядку

match начинает проверку с первой ветви, и первая успешно сопоставленная ветвь становится результатом — остальные не выполняются:

yaoxiang
number = 5

result = match number {
    _ => "Другое",   // подстановочный знак соответствует всему, здесь будет сопоставление
    5 => "Пять",     // никогда не выполнится — уже сопоставлено выше
}
print(result)  // "Другое"

Это означает, что размещение подстановочного знака _ в конце — хорошая практика.

Итог

ПунктОписание
Синтаксисmatch значение { шаблон => выражение, ... }
Выражениеmatch вычисляет значение, все ветви одного типа
Шаблон литералаТочное сопоставление: 200 => "OK"
Идентиф. шаблонЗахват значения в переменную: ok(value) => ...
Подстановочный_ соответствует любому значению, резерв
ИсчерпываемостьДолжны быть покрыты все возможные случаи
Несколько шаблоновшаблон1 | шаблон2 => выражение
Порядок выполненияСверху вниз, первое сопоставление побеждает

Следующий шаг: эта статья охватывает базовое использование match. Более продвинутые шаблоны (вложенные шаблоны, охраняющие выражения, деструктуризация структоров и т.д.) рассматриваются в Продвинутое сопоставление с образцом.