Устранение неоднозначности в перекрывающихся трейтах
Тип может реализовывать много разных трейтов. Что если два трейта будут требовать метод с одним и тем же именем? например, много трейтов могут иметь метод 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)