Методы в перечислениях
Часть раздела Объектно-ориентированное программирование путешествия по Rust на Coddy. Урок 15 из 61.
Как и структуры, enum могут иметь method, определённые в блоках impl. Это позволяет напрямую прикреплять поведение к вашему типу enum, упрощая работу с различными variants через единый интерфейс.
Вот как добавить метод в перечисление Message из предыдущего урока:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
impl Message {
fn describe(&self) -> String {
match self {
Message::Quit => String::from("Quit signal"),
Message::Move { x, y } => format!("Move to ({}, {})", x, y),
Message::Write(text) => format!("Message: {}", text),
}
}
}
Блок impl Message работает точно так же, как и для структур. Метод принимает &self, чтобы получить доступ к экземпляру перечисления. Внутри метода вы используете match, чтобы определить, с каким вариантом работаете, и вернуть подходящий результат.
Вызов метода выглядит одинаково независимо от того, какой variant у вас есть:
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Сигнал выхода
println!("{}", m2.describe()); // Перемещение в (10, 20)
}
Этот шаблон эффективен, потому что вызывающему коду не нужно знать, какой variant у него есть. Он просто вызывает method, а enum обрабатывает всё остальное внутри. Поведение меняется в зависимости от variant, но интерфейс остаётся неизменным.
Задание
ЛегкоДавайте создадим систему светофора, которая использует enum с методами для описания текущего состояния сигнала. Каждый цвет светофора будет содержать информацию о своей длительности, а метод предоставит понятное человеку описание.
Вы создадите два файла, чтобы организовать свой код:
traffic.rs: определите публичныйTrafficLightenum с тремя вариантами:Red: содержитu32, представляющий количество секунд ожиданияYellow: содержитu32, представляющий количество секунд ожиданияGreen: содержитu32, представляющий количество секунд движения
status, который возвращаетStringс описанием сигнала. Используйтеmatchвнутри метода, чтобы обработать каждый вариант и включить длительность в сообщение.main.rs: подключите модуль traffic, создайте экземпляры каждого варианта сигнала и вызовите методstatusдля каждого из них, чтобы вывести описания.
Метод status должен возвращать сообщения в следующих точных форматах:
- Для
Red:Stop for {seconds} seconds - Для
Yellow:Caution for {seconds} seconds - Для
Green:Go for {seconds} seconds
Ваша программа должна выводить состояние каждого сигнала в отдельной строке:
Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} secondsНапример, если длительность красного сигнала составляет 30 секунд, жёлтого — 5 секунд, а зелёного — 25 секунд, вывод будет таким:
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsВы получите три входных значения: длительность красного сигнала, длительность жёлтого сигнала и длительность зелёного сигнала.
Попробуйте сами
mod traffic;
use traffic::TrafficLight;
fn main() {
// Читаем ввод для длительностей
let mut red_input = String::new();
std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
let red_duration: u32 = red_input.trim().parse().expect("Invalid number");
let mut yellow_input = String::new();
std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");
let mut green_input = String::new();
std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
let green_duration: u32 = green_input.trim().parse().expect("Invalid number");
// TODO: Создать экземпляры каждого варианта TrafficLight с введёнными длительностями
// TODO: Вызвать метод status у каждого светофора и вывести результат
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media PlayerПотренируйтесь самостоятельно: Онлайн-компилятор Rust