Menu
Coddy logo textTech

Обобщённые методы

Часть раздела Объектно-ориентированное программирование путешествия по Rust на Coddy. Урок 25 из 61.

Generic-структура может хранить любой тип, но без методов для взаимодействия с its data она не очень полезна. Чтобы определить методы для generic-структуры, тебе нужен специальный синтаксис в блоке impl.

Главное — объявить параметр generic в самом impl:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

Обратите внимание на impl<T> перед Wrapper<T>. Это сообщает Rust, что T — параметр обобщённого типа для всего блока реализации. Без этого объявления Rust искал бы конкретный тип с именем T и не смог бы его найти.

Метод get возвращает &T: ссылку на тип, который содержит обёртка. Это работает независимо от того, является ли T значением типа integer, строкой или любым другим типом:

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

Одно и то же определение метода работает для обоих вариантов, потому что обобщённый тип T адаптируется к каждому конкретному типу во время компиляции.

challenge icon

Задание

Легко

Давайте расширим ваш generic контейнер с помощью методов! Вы создадите структуру Box (не путать со стандартным Box в Rust), которая может хранить любой тип и предоставляет методы для взаимодействия с её содержимым.

Вы организуете код в двух файлах:

  • mybox.rs: Define публичную generic структуру под названием MyBox<T> с private полем contents типа T. Implement методы для этой структуры:
    • ассоциированную функцию new, которая Creates новый MyBox с given значением
    • метод peek, который возвращает reference на contents (с использованием &self)
    • метод replace, который принимает новое значение и заменяет current contents (с использованием &mut self)
  • main.rs: Подключите свой модуль и продемонстрируйте работу generic методов с разными типами. Вы создадите контейнеры, заглянете в их contents и замените значения, чтобы показать методы в действии.

Remember ключевой синтаксис для реализации методов в generic структуре: перед MyBox<T> необходимо указать impl<T>, чтобы сообщить Rust, что T является generic параметром для всего блока реализации.

В основном файле продемонстрируйте работу вашего MyBox следующим образом:

  1. Создайте контейнер с integer (первый ввод, преобразованный в i32)
  2. Загляните в его contents и выведите значение
  3. Замените contents новым integer (второй ввод, преобразованный в i32)
  4. Снова загляните внутрь, чтобы показать обновлённое значение
  5. Создайте второй контейнер со строкой (третий ввод)
  6. Загляните в contents строкового контейнера

Ваш вывод должен соответствовать следующему формату:

Integer box contains: {value}
After replace: {value}
String box contains: {value}

Например, при вводе 10, 25 и Rust:

Integer box contains: 10
After replace: 25
String box contains: Rust

Вы получите три ввода: initial integer, replacement integer и строковое значение.

Попробуйте сами

mod mybox;

use mybox::MyBox;

fn main() {
    // Прочитать входные данные
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let initial_int: i32 = input1.trim().parse().expect("Invalid integer");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let replacement_int: i32 = input2.trim().parse().expect("Invalid integer");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let string_value = input3.trim().to_string();

    // TODO: Создать MyBox с начальным целым числом
    
    // TODO: Peek at its contents and print: "Integer box contains: {value}"
    
    // TODO: Заменить содержимое на целое число для замены
    
    // TODO: Peek again and print: "After replace: {value}"
    
    // TODO: Создать второй MyBox со строковым значением
    
    // TODO: Peek at the string box and print: "String box contains: {value}"
}
quiz iconПроверьте себя

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

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Rust