Menu
Coddy logo textTech

Несколько блоков реализации

Часть раздела 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, которые может иметь структура, не ограничено.

challenge icon

Задание

Легко

Создайте структуру Player с двумя полями: name (String) и score (u32).

Организуйте методы структуры в двух отдельных блоках реализации (impl):

Первый блок impl — конструктор и запрос:

  • new — ассоциированная функция, которая принимает name: String и возвращает Player со значением score, равным 0
  • get_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: Добавьте очки за второй раунд и выведите окончательный счет
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Object Oriented Programming