Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Розрізнення перекривних трейтів

Тип може реалізовувати багато різних трейтів. Що, якщо два трейтів обидва вимагають однакову назву для функції? Наприклад, багато трейтів можуть мати метод із назвою get(). Вони навіть можуть мати різні типи повернення!

Добра новина: оскільки кожна реалізація трейта отримує власний блок impl, зрозуміло, який саме метод get якого трейта ви реалізовуєте.

А як бути, коли настає час викликати ці методи? Щоб розрізнити їх, нам потрібно використовувати Fully Qualified Syntax.

trait UsernameWidget {
    // Отримати вибране ім'я користувача з цього віджета
    fn get(&self) -> String;
}

trait AgeWidget {
    // Отримати вибраний вік з цього віджета
    fn get(&self) -> u8;
}

// Форма і з UsernameWidget, і з AgeWidget
struct Form {
    username: String,
    age: u8,
}

impl UsernameWidget for Form {
    fn get(&self) -> String {
        self.username.clone()
    }
}

impl AgeWidget for Form {
    fn get(&self) -> u8 {
        self.age
    }
}

fn main() {
    let form = Form {
        username: "rustacean".to_owned(),
        age: 28,
    };

    // Якщо ви розкоментуєте цей рядок, ви отримаєте помилку з повідомленням
    // "multiple `get` found". Бо, зрештою, існує кілька методів
    // з назвою `get`.
    // println!("{}", form.get());

    let username = <Form as UsernameWidget>::get(&form);
    assert_eq!("rustacean".to_owned(), username);
    let age = <Form as AgeWidget>::get(&form);
    assert_eq!(28, age);
}

Дивіться також:

Розділ The Rust Programming Language про Fully Qualified syntax