Изучение Топаза

Данные и управление

Опишите учебные задачи номинальными записями в коллекции и подберите if, match и for для трёх различных решений.

Результат: вы опишете небольшую предметную область с помощью записи и коллекции, а затем подберёте if, match и for исходя из вопроса, на который отвечает каждая конструкция.

Что нужно знать: изучите раздел Значения и функции и разберитесь с привязками, аннотациями, параметрами и возвращаемыми значениями функций.

Задайте форму каждой задаче

Создайте файл data-control.tpz:

TOPAZ
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")

Повторите уже знакомые два шага:

BASH
topaz check data-control.tpz
topaz run data-control.tpz

Программа выводит:

Вывод
Run first program: done
Build application: focused
remaining: 25 minutes

Проследите три решения

УчебнаяЗадача — номинальная запись. record — это номинальный тип данных, который объединяет несколько связанных полей разных типов под единым именем. Мы используем запись вместо отдельных разрозненных переменных или простых кортежей, чтобы явно описать структуру сущности и сгруппировать название задачи, её длительность и статус выполнения. В приведённом коде объявление record УчебнаяЗадача задаёт поля название, минуты и выполнена, определяя отдельный тип значений предметной области. Поле выполнена имеет значение по умолчанию false, поэтому второй конструктор опускает его.

Array представляет собой упорядоченную коллекцию элементов одного типа, сохраняющую порядок добавления. Мы выбираем Array вместо других коллекций, так как для списка задач важен точный порядок их последовательной обработки и допустимо хранение повторяющихся элементов. В приведённом коде запись Array<УчебнаяЗадача> показывает, что задачи — упорядоченная коллекция таких записей.

record и Array задают форму и структуру данных, определяя способы хранения информации в программе. Конструкции for, if и match отвечают за управление потоком выполнения и определяют, как программа обрабатывает эти данные.

for — это конструкция цикла, которая последовательно перебирает каждый элемент коллекции. Мы применяем for вместо обращения по индексам, так как нам требуется выполнить одинаковые действия для каждого элемента массива от начала до конца. В приведённом коде выражение for задача in задачи обходит задачи в порядке элементов массива, поэтому вывод сохраняет тот же порядок.

if — это инструкция условного ветвления, которая выполняет блок кода при истинности логического выражения. Мы используем if, когда нужно ответить на один вопрос «да или нет» и принять решение о выполнении действия на основе состояния. В приведённом коде выражение if !задача.выполнена внутри цикла отвечает на один вопрос «да или нет» и увеличивает осталось только для незавершённой задачи, а первый if в функции темп досрочно возвращает результат для готовой задачи.

match — это конструкция сопоставления с шаблоном, которая сравнивает значение с набором образцов и выбирает соответствующую ветку. Мы выбираем match вместо серии последовательных проверок, так как нам нужно распределить числовое значение по нескольким диапазонам и получить итоговую строку. В приведённом коде темп отвечает на другой вопрос, где match классифицирует оставшиеся значения минуты по диапазонам 1..15, 16..30 и шаблону _, после чего строка соответствующей ветви становится результатом функции.

Особенность match заключается в том, что эта конструкция проверяет охват всех возможных вариантов значений. Шаблон _ перехватывает любые значения, не попавшие в предыдущие диапазоны 1..15 и 16..30. Это исключает ситуации, когда данные остаются без обработки, и делает поведение функции предсказуемым при любых входящих числах.

Выбор: Array, Map или Set?

Используйте Array, когда важны порядок и повторение элементов, как в этом сценарии. Map подходит, если основная операция — поиск по ключу. Выбирайте Set, когда уникальность важнее позиции. Ориентируйтесь на наблюдаемое поведение, а не на текущее количество элементов.

Попробуйте

Добавьте третьим элементом массива УчебнаяЗадача { название: "Review output", минуты: 5, выполнена: true }. Какая строка появится в выводе и изменится ли осталось?

Показать ответ

Появится Review output: done. Значение осталось останется равным 25 minutes, потому что новая задача уже выполнена и тело if для неё не запускается.

Готовы двигаться дальше, если

Вы можете объяснить, почему УчебнаяЗадача — запись, почему коллекция — Array, почему для обхода используется for, для накопления — if, а для классификации — match.

Подробные правила находятся в разделах Шаблоны и управление потоком, Записи и номинальные данные и Коллекции и включения. Переходите к разделу Ошибки и ресурсы.