Трейт Debug
Часть раздела Object Oriented Programming путешествия по Rust на Coddy — урок 35 из 61.
Стандартная библиотека Rust поставляется со множеством предопределенных типажей, которые обеспечивают общую функциональность. Одним из самых полезных для разработки является типаж Debug, который позволяет выводить содержимое структуры для проверки.
Если вы попытаетесь вывести пользовательскую структуру напрямую, Rust не будет знать, как её отобразить:
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Ошибка! Debug не реализован
Форматировщик {:?} требует трейт Debug. Вместо того чтобы реализовывать его вручную, Rust предоставляет сокращение — атрибут #[derive]. Разместите его непосредственно над определением вашей структуры:
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
Атрибут #[derive(Debug)] указывает компилятору автоматически создать реализацию Debug. Это работает до тех пор, пока все поля в вашей структуре также реализуют Debug (что делает большинство стандартных типов).
Для более читаемого вывода вложенных структур используйте {:#?} для «красивой» печати (pretty-printing):
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
Автоматический вывод Debug необходим во время разработки — он позволяет быстро проверять данные без написания собственного кода форматирования.
Задание
ЛегкоДавайте сделаем ваши структуры доступными для инспекции, производя типаж Debug! Вы создадите простую систему инвентаризации, где элементы можно будет выводить на печать для целей отладки.
Вы организуете свой код в двух файлах:
inventory.rs: Определите публичную структуруItemс двумя публичными полями:name(String) иquantity(u32). Используйте атрибут#[derive(Debug)]для автоматической реализации типажа Debug для вашей структуры.main.rs: Подключите модуль inventory и создайте экземплярItem, используя предоставленные входные данные. Выведите элемент, используя отладочный форматитор{:?}, чтобы отобразить его внутреннюю структуру.
Прелесть производного Debug заключается в том, что Rust автоматически генерирует код форматирования за вас — ручная реализация не требуется! Вашей структуре просто нужен атрибут, и она становится доступной для печати с помощью {:?}.
Ваш вывод должен отображать элемент в отладочном формате Rust:
Item { name: "{name}", quantity: {quantity} }Например, с входными данными Keyboard и 15:
Item { name: "Keyboard", quantity: 15 }Вы получите два входных значения: название элемента и количество (преобразуйте в u32).
Попробуйте сами
mod inventory;
use inventory::Item;
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 quantity_str = String::new();
std::io::stdin().read_line(&mut quantity_str).expect("Failed to read line");
let quantity: u32 = quantity_str.trim().parse().expect("Failed to parse quantity");
// TODO: Создайте экземпляр Item с заданным name и quantity
// TODO: Выведите элемент, используя отладочный форматтер {:?}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media Player