Rust: с нуля до своего органайзера Урок 27 из 35
Структура Task: данные с понятными именами
Урок 27. Собрать название, длительность и состояние задачи в один собственный тип.
Текст переведён с помощью ИИ.
Предварительно: уроки 9, 11, 19, 22 и 26. Если круглые скобки кортежа ещё непривычны, вернитесь к уроку 26.
Образ и опорная карта
На карточке задачи есть подписанные графы: «название», «минуты», «сделано». В кортеже пришлось бы помнить, что означает .0 или .1. Структура (struct) — собственный тип с именованными полями. Поле хранит одну часть значения; экземпляр — конкретная заполненная карточка. Образ ограничен: бумажная форма не проверяет тип написанного, а компилятор требует указанные поля и их типы. При этом структура сама по себе не проверяет смысл, например что минут больше нуля.
Тип Task → поля → экземпляр → чтение через точку → изменение через mut. Проговорите карту до примера. Ключевое слово struct объявляет тип. После Task стоят фигурные скобки с полями вида имя: тип, разделёнными запятыми. Это описание формы, а не созданная задача. Имя Task пишем с большой буквы по принятому в Rust стилю типов.
Заполняем карточку
Сохраните прежний src/main.rs проекта organizer, замените его целиком и выполните cargo run рядом с Cargo.toml. Другие файлы и зависимости не меняются. Сначала предскажите результат.
Task { title: ..., minutes: ..., done: ... } создаёт экземпляр. В отличие от кортежа, каждому значению здесь соответствует имя поля. task.title читает поле после точки. Значение String не нужно перемещать ради печати: println! использует его для форматирования, и после печати задача остаётся доступна. done имеет уже знакомый тип bool. Запятая после последнего поля допускается и помогает добавлять поля без изменения предыдущей строки.
struct Task {
title: String,
minutes: u32,
done: bool,
}
fn main() {
let task = Task {
title: String::from("Чтение"),
minutes: 20,
done: false,
};
println!("Задача: {}", task.title);
println!("Минут: {}", task.minutes);
println!("Сделано: {}", task.done);
}
Задача: Чтение
Минут: 20
Сделано: false
Порядок перечисления полей при создании может отличаться от порядка объявления: имена удерживают смысл.
Меняем запись и проверяем смысл
let mut task разрешает менять поля этого экземпляра. task.done = true записывает новое логическое значение; точка здесь обращается к полю, а не к методу. Для определения структуры mut не требуется. Проверка task.minutes > 0 — наше правило для органайзера, а не встроенная гарантия struct: нулевое число имело бы правильный тип u32, но неверный смысл для этой задачи.
struct Task {
title: String,
minutes: u32,
done: bool,
}
fn main() {
let mut task = Task {
title: String::from("Прогулка"),
minutes: 30,
done: false,
};
if task.minutes > 0 {
task.done = true;
}
println!("{}: {}", task.title, task.done);
}
Прогулка: true
Здесь условие лишь показывает место проверки. Позже введём способ, который не позволит создать неподходящую задачу через отдельную функцию и сообщит причину ошибки. Пока ввод пользователя не принимаем, поэтому не выдаём этот пример за полную проверку данных.
Все объявленные поля надо заполнить. В следующем отдельном примере забыто done, и компилятор сообщает E0063:
struct Task {
title: String,
minutes: u32,
done: bool,
}
fn main() {
let task = Task {
title: String::from("Чтение"),
minutes: 20,
};
println!("{}", task.title);
}
Компилятор проверяет наличие и тип полей, но не знает, сколько минут разумно выделить для прогулки. Так заканчивается полезность образа «готовой формы».
Проверка понимания
- Чем
Taskотличается от одногоtask? - Почему
task.minutesяснее, чемreport.1? - Гарантирует ли
minutes: u32, что минут больше нуля?
Проверьте: первое — описание типа, второе — экземпляр; имя поля сообщает его роль; нет, ноль входит в u32. Воспроизведите карту по памяти.
Задание
Обязательное. Объявите Task с тремя полями из урока. Создайте изменяемую задачу Уборка, 15 минут, false; выведите Уборка: 15 мин, сделано false, затем измените done на true и выведите После: true. Используйте значения полей, не вписывайте результат готовой строкой.
Граница. Попробуйте создать задачу без minutes, прочитайте сообщение компилятора и верните поле.
Подсказка
Нужны let mut task = Task { ... };, затем task.done = true;. В println! передайте поля либо подставьте их по именам.
Эталон после попытки
struct Task {
title: String,
minutes: u32,
done: bool,
}
fn main() {
let mut task = Task {
title: String::from("Уборка"),
minutes: 15,
done: false,
};
println!(
"{}: {} мин, сделано {}",
task.title, task.minutes, task.done
);
task.done = true;
println!("После: {}", task.done);
}
Уборка: 15 мин, сделано false
После: true
Теперь данные задачи лежат вместе и читаются по именам. Поведение рядом с ними добавим в следующем уроке. Официальный разбор структур.
Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом
Комментарии (0)
Войдите, чтобы оставить комментарий →
Пока нет комментариев. Будьте первым.