Перейти к основному содержимому
Модуль 5 · Урок 2 из 210/14 в курсе~15 min
Уроки модуля (2/2)

Черты и границы черт

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

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


Определение и реализация черты

Чтобы определить признак, мы используем ключевое слово trait, за которым следуют сигнатуры методов, которые должны определять реализующие типы:

Rust
pub trait Summary {
    fn summarize(&self) -> String;
}

Чтобы реализовать признак конкретного типа, мы используем синтаксис impl TraitName for TypeName:

Rust
pub struct NewsArticle {
    pub headline: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}", self.headline)
    }
}

Границы черт

При написании универсальных функций мы можем ограничить параметры типа, чтобы гарантировать, что они реализуют определенную особенность. Стандартный синтаксис: <T: Trait>:

Rust
pub fn notify<T: Summary>(item: &T) {
    println!("Notification: {}", item.summarize());
}

Альтернативно, для более сложных подписей мы можем использовать предложение where:

Rust
pub fn notify_advanced<T>(item: &T)
where
    T: Summary
{
    println!("Notification: {}", item.summarize());
}

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

Упражнение 1: Суммарная черта

Упражнение#rust.m5.l2.e1
Попыток: 0Загрузка…

Определите признак с именем Summary, содержащий сигнатуру метода fn summ(&self) -> String;. Затем определите структуру NewsArticle с полем заголовка типа String и реализуйте для нее свойство Summary, чтобы метод summous возвращал значение поля заголовка.

Загрузка редактора…
Показать подсказку

Определите атрибут «Summary» и структуру «NewsArticle». Реализуйте с помощью impl Summary for NewsArticle, клонируя поле self.headline.clone().

Решение доступно после 3 попыток

Упражнение 2. Границы признаков с помощью print_summary

Упражнение#rust.m5.l2.e2
Попыток: 0Загрузка…

На основе кода из предыдущего упражнения определите универсальную функцию с именем print_summary<T>, которая принимает элемент параметра типа &T. Примените черту, связанную так, чтобы T реализовывал черту Summary. Внутри функции распечатайте результат, возвращаемый item.summarize().

Загрузка редактора…
Показать подсказку

Используйте подпись `fn print_summary<T: Summary>(item: &T)`и вызовите`item.summarize()` внутри`println!`.

Решение доступно после 3 попыток

Упражнение 3. Расчет площади с использованием признаков

Упражнение#rust.m5.l2.e3
Попыток: 0Загрузка…

Определите признак с именем Area с помощью метода fn area(&self) -> f64;. Создайте структуру Circle, содержащую поле радиуса типа f64, и реализуйте для нее признак Area, вычислив площадь (формула: радиус * радиус * 3,14159).

Загрузка редактора…
Показать подсказку

Определите атрибут Area и структуру Circle. Реализуйте `area(&self)`, используя формулу площади круга.

Решение доступно после 3 попыток