Трейт Display
Часть раздела Object Oriented Programming путешествия по Rust на Coddy — урок 36 из 61.
В то время как Debug отлично подходит для разработчиков, проверяющих данные, типаж Display предназначен для пользовательского вывода. Именно он обеспечивает работу форматировщика {} в println!. В отличие от Debug, Rust не может автоматически реализовать (derive) Display — вы должны реализовать его вручную.
Для реализации Display вам необходимо импортировать модуль fmt и реализовать метод fmt:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
Метод fmt принимает Formatter и возвращает fmt::Result. Вы используете макрос write! для форматирования вывода, обращаясь к полям структуры через self.
Теперь вы можете вывести структуру с помощью стандартного форматировщика {}:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
Ключевое отличие: вывод Debug показывает структуру ваших данных (полезно для отладки), в то время как вывод Display отполирован и предназначен для конечных пользователей. Структура может реализовывать и то, и другое — используйте {:?} для отладки и {} для чистого вывода.
Задание
ЛегкоДавайте создадим удобную для пользователя систему отображения товаров! В то время как Debug показывает необработанную структуру ваших данных, типаж Display позволяет создавать отполированный, понятный человеку вывод, идеально подходящий для конечных пользователей.
Вы организуете свой код в двух файлах:
product.rs: Определите публичную структуруProductс двумя публичными полями:name(String) иprice(f64). Реализуйте типажDisplayдля вашей структуры, чтобы она форматировалась как{name} - ${price}. Не забудьте подключитьstd::fmtи использовать макросwrite!внутри вашего методаfmt.main.rs: Подключите модуль product и создайте экземплярProduct, используя предоставленные входные данные. Выведите продукт, используя стандартный форматор{}, чтобы показать ваш пользовательский вывод.
Типаж Display требует от вас ручной реализации метода fmt — Rust не может вывести его автоматически, как Debug. Это дает вам полный контроль над тем, как ваш тип выглядит для пользователей.
Ваш вывод должен отображать продукт в чистом, удобном для пользователя формате:
{name} - ${price}Например, при входных данных Wireless Mouse и 29.99:
Wireless Mouse - $29.99Вы получите два входных значения: название продукта и цену (преобразуйте в f64).
Шпаргалка
Трейт Display предназначен для пользовательского вывода и используется форматировщиком {} в println!. В отличие от Debug, его необходимо реализовывать вручную.
Чтобы реализовать Display, подключите модуль fmt и реализуйте метод fmt:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
Метод fmt принимает Formatter и возвращает fmt::Result. Используйте макрос write! для форматирования вывода, обращаясь к полям структуры через self.
Выведите структуру с помощью форматировщика {}:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
Ключевое отличие: Debug ({:?}) показывает структуру данных для отладки, в то время как Display ({}) обеспечивает понятный вывод для конечных пользователей.
Попробуйте сами
mod product;
use product::Product;
fn main() {
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = 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: Создайте экземпляр Product с именем и ценой
// TODO: Выведите продукт, используя форматировщик {}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media Player