0Pricing
Learn Rust Coding · Урок

Методы по умолчанию

Значения по умолчанию трейтов

«Методы по умолчанию» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.

Методы с телом

Методы трейта не обязаны состоять только из сигнатур. Трейт может предоставлять реализацию по умолчанию — тело метода, которое реализующие типы получают автоматически.

Это уменьшает количество шаблонного кода для множества типов.

Метод по умолчанию

Напишите тело прямо внутри трейта. Типы, реализующие трейт, бесплатно наследуют его без дополнительного кода.

trait Greet {
    fn hello(&self) -> String {
        String::from("Hello there")
    }
}

struct Robot;
impl Greet for Robot {}

fn main() {
    println!("{}", Robot.hello());
}

Переопределение реализации по умолчанию

Любой реализующий тип может переопределить реализацию по умолчанию, предоставив собственную версию. Для этого типа переопределение заменяет реализацию по умолчанию.

trait Greet {
    fn hello(&self) -> String { String::from("Hello there") }
}

struct Robot;
struct Pirate;
impl Greet for Robot {}
impl Greet for Pirate {
    fn hello(&self) -> String { String::from("Arr!") }
}

fn main() {
    println!("{}", Robot.hello());
    println!("{}", Pirate.hello());
}

Реализации по умолчанию вызывают обязательные методы

Метод по умолчанию может вызывать другие методы того же трейта, даже если для них нет реализации по умолчанию. Это мощный подход: реализующие типы предоставляют небольшое ядро, а реализации по умолчанию строят на нём более сложное поведение.

trait Summary {
    fn title(&self) -> String;
    fn preview(&self) -> String {
        format!("Read more about: {}", self.title())
    }
}

struct Article { headline: String }
impl Summary for Article {
    fn title(&self) -> String { self.headline.clone() }
}

fn main() {
    let a = Article { headline: String::from("Rust Rocks") };
    println!("{}", a.preview());
}

Шаблонный метод

Сочетание обязательных методов и методов по умолчанию называется паттерном шаблонного метода. Трейт определяет общий поток выполнения в реализациях по умолчанию, оставляя изменяемые части обязательным методам.

trait Report {
    fn body(&self) -> String;
    fn render(&self) -> String {
        format!("=== REPORT ===\n{}\n==============", self.body())
    }
}

struct Sales;
impl Report for Sales {
    fn body(&self) -> String { String::from("Sales up 10%") }
}

fn main() {
    println!("{}", Sales.render());
}

Несколько реализаций по умолчанию

Трейт может свободно сочетать обязательные методы и методы по умолчанию. Реализующим типам нужно предоставить только обязательные методы.

trait Animal {
    fn name(&self) -> String;
    fn legs(&self) -> u32 { 4 }
    fn describe(&self) -> String {
        format!("{} has {} legs", self.name(), self.legs())
    }
}

struct Dog;
impl Animal for Dog {
    fn name(&self) -> String { String::from("Dog") }
}

fn main() {
    println!("{}", Dog.describe());
}

Реализации по умолчанию и стандартные трейты

Многие стандартные трейты используют реализации по умолчанию. Например, Iterator требует только next; каждый адаптер и потребитель является методом по умолчанию, построенным на его основе.

Поэтому один метод открывает доступ ко всему набору инструментов.

Переопределение ради производительности

Иногда реализация по умолчанию работает, но специализированная версия быстрее. Реализующие типы могут переопределить только этот метод, сохранив остальные реализации по умолчанию.

trait Counter {
    fn items(&self) -> Vec<i32>;
    fn total(&self) -> i32 {
        self.items().iter().sum()
    }
}

struct Fast { precomputed: i32 }
impl Counter for Fast {
    fn items(&self) -> Vec<i32> { vec![] }
    fn total(&self) -> i32 { self.precomputed }
}

fn main() {
    println!("{}", Fast { precomputed: 99 }.total());
}

Удобные трейты

Хороший дизайн трейта: сделать обязательными небольшое количество методов, а для остальных предоставить удобные реализации по умолчанию. Реализующим типам требуется минимум работы, но они получают богатый интерфейс.

Оговорка

Метод по умолчанию может использовать только другие методы трейта и тип за self через них; он не может напрямую обращаться к полям неизвестного реализующего типа. Стройте реализации по умолчанию вокруг собственных методов трейта.

Реализации по умолчанию и обязательные методы: кратко

Метод трейта с телом является реализацией по умолчанию, а метод только с сигнатурой — обязательным. Реализующие типы должны предоставить каждый обязательный метод, но могут оставить реализации по умолчанию без изменений.

trait Logger {
    fn line(&self) -> String;
    fn log(&self) {
        println!("LOG: {}", self.line());
    }
}

struct App;
impl Logger for App {
    fn line(&self) -> String { String::from("started") }
}

fn main() {
    App.log();
}

Быстрая проверка

Проверьте своё понимание методов по умолчанию.

Итоги

Вы изучили реализации трейтов по умолчанию:

  • Метод трейта может содержать тело как реализацию по умолчанию
  • Реализующие типы бесплатно наследуют её и могут переопределить
  • Реализации по умолчанию могут вызывать обязательные методы, поддерживая паттерн шаблонного метода
  • Так трейты остаются удобными, требуя небольшого набора обязательных методов

Часто задаваемые вопросы

Урок «Методы по умолчанию» бесплатный?

Да — полный текст урока «Методы по умолчанию» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.

Чему я научусь в уроке «Методы по умолчанию»?

Значения по умолчанию трейтов Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Learn Rust Coding?

Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Методы по умолчанию»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Learn Rust Coding?

Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Определение трейтов
  2. Объекты трейтов и dyn
  3. Статическая и динамическая диспетчеризация
  4. Методы по умолчанию
← Назад к Learn Rust Coding