Disambiguating overlapping traits
A type can implement many different traits. What if two traits both require the same name for a function? For example, many traits might have a method named get(). They might even have different return types!
Good news: because each trait implementation gets its own impl block with a unique name, it's clear which trait's get method you're implementing.
What about when it comes time to call those methods? To disambiguate between them, we have to use Fully Qualified Syntax.
trait UsernameWidget<T> {
// Get the selected username out of this widget
fn get(self: @T) -> ByteArray;
}
trait AgeWidget<T> {
// Get the selected age out of this widget
fn get(self: @T) -> u8;
}
// A form with both a UsernameWidget and an AgeWidget
#[derive(Drop)]
struct Form {
username: ByteArray,
age: u8,
}
impl FormUsername of UsernameWidget<Form> {
fn get(self: @Form) -> ByteArray {
self.username.clone()
}
}
impl FormAge of AgeWidget<Form> {
fn get(self: @Form) -> u8 {
*self.age
}
}
fn main() {
let form = Form { username: "caironaute", age: 28 };
// If you uncomment this line, you'll get an error saying
// "Ambiguous method call". Because, after all, there are multiple methods
// named `get`.
// println!("{}", form.get());
let username = UsernameWidget::get(@form);
assert!(username == "caironaute");
let age = AgeWidget::get(@form);
assert!(age == 28);
}