Реализация трейтов
Часть раздела Object Oriented Programming путешествия по Rust на Coddy. Урок 30 из 61.
Теперь, когда вы знаете, как определять типаж, давайте посмотрим, как заставить структуру соответствовать этому контракту. Реализация типажа связывает абстрактное требование с конкретным поведением.
Синтаксис использует impl TraitName for StructName:
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
Блок impl Speak for Dog сообщает Rust, что Dog реализует типаж Speak. Внутри вы предоставляете фактическое тело метода — именно здесь вы определяете, как говорит собака.
Сила типажей становится очевидной, когда несколько типов реализуют один и тот же типаж:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
Теперь и Dog, и Cat обладают способностью Speak, но каждый предоставляет свою собственную уникальную реализацию. Вы можете вызвать .speak() для любого из этих типов:
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex говорит: Woof!
println!("{}", cat.speak()); // Whiskers говорит: Meow!
Это основа полиморфизма в Rust — разные типы, один и тот же интерфейс, уникальное поведение.
Задание
ЛегкоДавайте воплотим типажи (traits) в жизнь, реализовав их для различных типов! Вы создадите типаж Describable и реализуете его для двух разных структур, каждая из которых будет предоставлять свое уникальное описание.
Вы организуете свой код в трех файлах:
describable.rs: Определите публичный типажDescribableс методомdescribe(&self) -> String.items.rs: Создайте две публичные структуры, которые реализуют ваш типаж:Bookс публичным полемtitle(String)Movieс публичным полемname(String)
Describableсо своим собственным уникальным форматом описания.main.rs: Объедините ваши модули, создайте экземпляры обеих структур и вызовите их методыdescribe, чтобы показать, как один и тот же типаж выдает разные результаты для разных типов.
Ваша структура Book должна описывать себя как Book: {title}, а ваша Movie должна описывать себя как Film: {name}. Обратите внимание, как каждый тип выполняет один и тот же контракт, но со своим собственным поведением!
В основном файле создайте книгу и фильм, используя два предоставленных входных значения, а затем выведите их описания на отдельных строках.
Ваш вывод должен соответствовать следующему формату:
Book: {title}
Film: {name}Например, при входных данных 1984 и Inception:
Book: 1984
Film: InceptionВы получите два входных значения: название книги и название фильма.
Попробуйте сами
mod describable;
mod items;
use describable::Describable;
use items::{Book, Movie};
fn main() {
// Чтение входных данных
let mut title = String::new();
std::io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
// TODO: Создать экземпляр Book с названием title
// TODO: Создать экземпляр Movie с названием name
// TODO: Вывести описание книги
// TODO: Вывести описание фильма
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media PlayerПотренируйтесь самостоятельно: Онлайн-компилятор Rust