Несколько блоков реализации
Часть раздела Object Oriented Programming путешествия по Rust на Coddy — урок 5 из 61.
Rust позволяет разделять методы структуры на несколько блоков impl. Хотя всё можно поместить в один блок, их разделение может сделать ваш код более организованным и читаемым.
Вот структура, функциональность которой разделена на два блока реализации:
struct BankAccount {
balance: f64,
}
// Конструктор и базовые запросы
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// Методы транзакций
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
Оба блока работают вместе бесшовно — Rust воспринимает их как единое целое. Вы можете вызывать любой метод независимо от того, в каком блоке он определен:
fn main() {
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
}
Этот паттерн становится особенно полезным по мере роста ваших структур. Вы можете группировать конструкторы вместе, отделять методы только для чтения от изменяющих методов или организовывать их по функциональности. Количество блоков impl, которые может иметь структура, не ограничено.
Задание
ЛегкоСоздайте структуру Player с двумя полями: name (String) и score (u32).
Организуйте методы структуры в двух отдельных блоках реализации (impl):
Первый блок impl — конструктор и запрос:
new— ассоциированная функция, которая принимаетname: Stringи возвращаетPlayerсо значениемscore, равным0get_score— принимает&selfи возвращает текущий счет какu32
Второй блок impl — изменение счета:
add_points— принимает&mut selfиpoints: u32, добавляет очки к счетуreset_score— принимает&mut selfи сбрасывает счет до0
Вы получите три входных значения:
- Первая строка: имя игрока (String)
- Вторая строка: очки для добавления в первом раунде (u32)
- Третья строка: очки для добавления во втором раунде (u32)
Создайте игрока с помощью Player::new, добавьте очки за первый раунд, выведите счет, затем сбросьте счет, добавьте очки за второй раунд и выведите итоговый счет.
Ожидаемый формат вывода:
{score_after_first_round}
{score_after_reset_and_second_round}Шпаргалка
Rust позволяет разделять методы структуры на несколько блоков impl для лучшей организации:
struct BankAccount {
balance: f64,
}
// Первый блок impl
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// Второй блок impl
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
Все методы из разных блоков impl бесшовно работают вместе:
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
Количество блоков impl для одной структуры не ограничено. Этот паттерн полезен для группировки связанной функциональности, например, для отделения конструкторов от мутирующих методов.
Попробуйте сами
use std::io;
// TODO: Определите структуру Player с полями name (String) и score (u32)
// TODO: Первый блок impl - Конструктор и методы запроса (new, get_score)
// TODO: Второй блок impl - Методы изменения счета (add_points, reset_score)
fn main() {
let mut input = String::new();
// Чтение имени игрока
io::stdin().read_line(&mut input).expect("Failed to read line");
let name = input.trim().to_string();
// Чтение очков за первый раунд
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let first_round: u32 = input.trim().parse().expect("Invalid number");
// Чтение очков за второй раунд
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let second_round: u32 = input.trim().parse().expect("Invalid number");
// TODO: Создайте игрока, используя Player::new
// TODO: Добавьте очки за первый раунд и выведите счет
// 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