Итоги — Обобщённый принтер
Часть раздела Объектно-ориентированное программирование путешествия по Rust на Coddy. Урок 44 из 61.
Задание
ЛегкоДавайте создадим гибкую систему объявлений, демонстрирующую возможности ограничений trait! Вы создадите trait Printable и generic function, которая может объявлять любой тип, реализующий этот trait: это покажет, как generics и traits работают вместе для создания повторно используемого, типобезопасного кода.
Вы организуете код в двух файлах:
printable.rs: Define public traitPrintableсprint_infomethod, который принимает&selfи returnsString. Затем создайте public generic function с именемannounce, которая принимает любой типT, реализующийPrintable. Эта function should printAnnouncement: {info}, где{info}— result вызоваprint_info()для item.main.rs: Создайте две public структуры, реализующиеPrintable:Person: с publicnamefield (String). Еёprint_infoshould returnPerson: {name}Product: с publicname(String) иprice(f64) fields. Еёprint_infoshould returnProduct: {name} - ${price}
announceдля каждого, чтобы продемонстрировать, что ваша generic function работает с любым типомPrintable.
Преимущество этого дизайна в том, что announce не имеет значения, получает ли она Person, Product или любой будущий тип. Требуется только, чтобы тип мог предоставлять информацию через print_info(). Ограничение trait гарантирует это во время компиляции.
Ваш output должен показать оба объявления:
Announcement: Person: {name}
Announcement: Product: {product_name} - ${price}Например, с inputs Alice, Laptop и 999.99:
Announcement: Person: Alice
Announcement: Product: Laptop - $999.99Вы получите три inputs: имя person, имя product и цену product (parse как f64).
Попробуйте сами
mod printable;
use printable::{Printable, announce};
// TODO: Определите публичную структуру Person с публичным полем name (String)
// Реализуйте трейт Printable для Person
// print_info должен возвращать "Person: {name}"
// TODO: Определите публичную структуру Product с публичными полями name (String) и price (f64)
// Реализуйте трейт Printable для Product
// print_info должен возвращать "Product: {name} - ${price}"
fn main() {
// Читаем входные данные
let mut person_name = String::new();
std::io::stdin().read_line(&mut person_name).expect("Failed to read line");
let person_name = person_name.trim().to_string();
let mut product_name = String::new();
std::io::stdin().read_line(&mut product_name).expect("Failed to read line");
let product_name = product_name.trim().to_string();
let mut price_input = String::new();
std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
let price: f64 = price_input.trim().parse().expect("Failed to parse price");
// TODO: Создайте экземпляр Person с person_name
// TODO: Создайте экземпляр Product с product_name и price
// TODO: Вызовите announce с Person
// TODO: Вызовите announce с Product
}
Все уроки раздела Объектно-ориентированное программирование
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media PlayerПотренируйтесь самостоятельно: Онлайн-компилятор Rust