Эта страница описывает Топаз v5.17. Прежде чем считать её актуальной, сверьте поле version в /version.json со значением 5.17.
Используйте if, когда нужно проверить одно условие, match — когда результат зависит от формы или категории значения, а for — когда действие повторяется для каждого элемента. Шаблоны внутри match и for одновременно проверяют данные и дают имена нужным частям.
Запустите пример
Сохраните код в файле data-control.tpz:
record УчебнаяЗадача {
название: string,
минуты: int,
выполнена: bool = false,
}
function темп(задача: УчебнаяЗадача) -> string {
if задача.выполнена {
return "done"
}
match задача.минуты {
case 1..15 => "quick"
case 16..30 => "focused"
case _ => "deep"
}
}
let задачи: Array<УчебнаяЗадача> = [
УчебнаяЗадача { название: "Run first program", минуты: 10, выполнена: true },
УчебнаяЗадача { название: "Build application", минуты: 25 },
]
let mut осталось = 0
for задача in задачи {
if !задача.выполнена {
осталось = осталось + задача.минуты
}
print("{задача.название}: {темп(задача)}")
}
print("remaining: {осталось} minutes")Сначала проверьте программу, затем выполните её:
topaz check data-control.tpz
topaz run data-control.tpz
Строки появятся в порядке элементов массива:
Run first program: done
Build application: focused
remaining: 25 minutesПроследите за тремя решениями
Цикл связывает очередной элемент массива с именем task. Вложенный if отвечает на один вопрос: задача ещё не выполнена? Здесь не требуется ни разбирать значение на части, ни выбирать из нескольких категорий.
Когда важны оба исхода, пишите if condition { ... } else { ... }.
Если ветви возвращают совместимые значения, весь if тоже является значением.
В функции темп первый if отдельно обрабатывает выполненную задачу. Затем match вычисляет задача.минуты один раз и проверяет ветки case сверху вниз. 1..15 и 16..30 — шаблоны диапазонов. _ принимает все остальные целые числа, поэтому результат определён для любого входа.
| Форма | Когда выбирать | Результат |
|---|---|---|
if | Выбор зависит от одного логического условия | Значение при совместимых результатах ветвей либо только действие |
match | У значения есть несколько значимых форм или категорий | Значение выбранной ветви и доступные в ней связанные имена |
for | Нужно посетить каждый элемент в установленном порядке | Действия в позиции инструкции либо Array результатов в позиции выражения |
Шаблон проверяет и связывает
Литеральный шаблон и шаблон диапазона проверяют значение. Имя вроде task связывается с совпавшим значением. Шаблоны конструкторов Some(value) и Err(message) извлекают содержимое Option и Result. Шаблон записи выбирает поля по именам.
В шаблоне массива остаток обозначается .., а не .... Форма case [head, ..tail] => связывает первый элемент с head, а остальные — с tail типа Array. Если оставшееся значение не нужно, используйте _.
Форма if let pattern = value { ... } удобна, когда важен один успешный вариант и, возможно, запасная ветвь. while let повторяет ту же проверку до первого несовпадения. Созданные ими имена неизменяемы и видны только в успешном блоке.
Частая ошибка
Не пишите [head, ...tail] в шаблоне. ... раскрывает массив в литерале или аргументы при вызове. Каноническая запись остатка списка — [head, ..tail].
Создание и разбор перечисления тоже записываются по-разному. Значение создают с именем перечисления, например Состояние.Приостановлен("review"), а в шаблоне оставляют только вариант: case Приостановлен(причина) =>.
Точные правила, влияющие на выбор
- Ветви
ifилиmatch, используемых как значение, должны давать совместимые результаты. - Для закрытого перечисления проверяется полнота вариантов. Ветка с дополнительным условием не засчитывается как полное покрытие варианта.
- Если проверяющий не может доказать полноту
match, добавьте явную ветвь_. - Части шаблона проверяются слева направо. Имена из неудачной альтернативы не переходят в следующую.
- Несовпадение допускающего отказ шаблона во включении коллекции вызывает ошибку, а не пропускает элемент. Для фильтрации добавьте явное условие
if. - Порядок обхода определён для
Array, целочисленных диапазонов,Setиmap.keys. Строки напрямую не обходятся. whileиforв позиции инструкции не дают значения.forв позиции выражения собирает результаты тела в исходном порядке.
Пользовательские шаблоны и итераторы, генераторы, перехват ошибок выполнения и метки на while или for в текущий язык не входят.
Начните с примера курса Данные и управление. Формы данных подробно разобраны в разделе Записи и номинальные данные, а порядок обхода и фильтрация — в разделе Коллекции и включения.