Результат: вы опишете небольшую предметную область записью и коллекцией, а затем выберете if, match и for по вопросу, на который отвечает каждая конструкция.
Что нужно знать: завершите Значения и функции и разберитесь с привязками, аннотациями, параметрами и результатами функций.
Задайте форму каждой задаче
Создайте data-control.tpz:
record StudyTask {
title: string,
minutes: int,
done: bool = false,
}
function pace(task: StudyTask) -> string {
if task.done {
return "done"
}
match task.minutes {
case 1..15 => "quick"
case 16..30 => "focused"
case _ => "deep"
}
}
let tasks: Array<StudyTask> = [
StudyTask { title: "Run first program", minutes: 10, done: true },
StudyTask { title: "Build application", minutes: 25 },
]
let mut remaining = 0
for task in tasks {
if !task.done {
remaining = remaining + task.minutes
}
print("{task.title}: {pace(task)}")
}
print("remaining: {remaining} minutes")Повторите уже знакомые два шага:
topaz check data-control.tpz
topaz run data-control.tpz
Программа печатает:
Run first program: done
Build application: focused
remaining: 25 minutesПроследите три решения
StudyTask — номинальная запись: её имя и поля задают один вид значения предметной области. У done есть значение по умолчанию false, поэтому второй конструктор опускает это поле. Array<StudyTask> сообщает, что tasks — упорядоченная коллекция таких записей.
for посещает задачи в порядке массива, поэтому вывод следует тому же порядку. Внутри цикла if !task.done отвечает на один вопрос «да или нет» и увеличивает remaining только для незавершённой задачи.
pace отвечает на другой вопрос. Первый if досрочно возвращает результат для готовой задачи. Затем match классифицирует оставшиеся значения minutes по диапазонам, и строка каждой ветви становится результатом функции.
Выбор: Array, Map или Set?
Используйте Array, когда важны порядок и повторения, как в этом плане. Map подходит, если основная операция — поиск по ключу. Выбирайте Set, когда уникальность важнее позиции. Ориентируйтесь на наблюдаемое поведение, а не на сегодняшнее количество элементов.
Попробуйте
Добавьте третьим элементом массива StudyTask { title: "Review output", minutes: 5, done: true }. Какая строка появится и изменится ли remaining?
Показать ответ
Появится Review output: done. Значение remaining останется равным 25 minutes, потому что новая задача уже выполнена и тело if для неё не запускается.
Готовы двигаться дальше, если
Вы можете объяснить, почему StudyTask — запись, почему коллекция — Array, почему обход использует for, накопление — if, а классификация — match.
Самостоятельные правила находятся в разделах Шаблоны и управление потоком, Записи и номинальные данные и Коллекции и включения. Переходите к Ошибкам и ресурсам.