Sometimes, functions can have the same names. Consider this code:
fn main() { trait Foo { fn f(&self); } trait Bar { fn f(&self); } struct Baz; impl Foo for Baz { fn f(&self) { println!("Baz’s impl of Foo"); } } impl Bar for Baz { fn f(&self) { println!("Baz’s impl of Bar"); } } let b = Baz; }trait Foo { fn f(&self); } trait Bar { fn f(&self); } struct Baz; impl Foo for Baz { fn f(&self) { println!("Baz’s impl of Foo"); } } impl Bar for Baz { fn f(&self) { println!("Baz’s impl of Bar"); } } let b = Baz;
If we were to try to call b.f()`b.f()`, we’d get an error:
error: multiple applicable methods in scope [E0034]
b.f();
^~~
note: candidate #1 is defined in an impl of the trait `main::Foo` for the type
`main::Baz`
fn f(&self) { println!("Baz’s impl of Foo"); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate #2 is defined in an impl of the trait `main::Bar` for the type
`main::Baz`
fn f(&self) { println!("Baz’s impl of Bar"); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We need a way to disambiguate which method we need. This feature is called ‘universal function call syntax’, and it looks like this:
fn main() { trait Foo { fn f(&self); } trait Bar { fn f(&self); } struct Baz; impl Foo for Baz { fn f(&self) { println!("Baz’s impl of Foo"); } } impl Bar for Baz { fn f(&self) { println!("Baz’s impl of Bar"); } } let b = Baz; Foo::f(&b); Bar::f(&b); }Foo::f(&b); Bar::f(&b);
Let’s break it down.
fn main() { Foo:: Bar:: }Foo:: Bar::
These halves of the invocation are the types of the two traits: Foo`Fooand` and
Bar`Bar`. This is what ends up actually doing the disambiguation between the two:
Rust calls the one from the trait name you use.
f(&b)
When we call a method like b.f()`b.f()using [method syntax][methodsyntax], Rust will automatically borrow` using method syntax, Rust
will automatically borrow b`bif` if f()`f()takes` takes &self`&self. In this case, Rust will not, and so we need to pass an explicit`. In this case, Rust will
not, and so we need to pass an explicit &b`&b`.
The form of UFCS we just talked about:
fn main() { Trait::method(args); }Trait::method(args);
Is a short-hand. There’s an expanded form of this that’s needed in some situations:
fn main() { <Type as Trait>::method(args); }<Type as Trait>::method(args);
The <>::`<>::syntax is a means of providing a type hint. The type goes inside the` syntax is a means of providing a type hint. The type goes inside
the <>`<>s. In this case, the type is`s. In this case, the type is Type as Trait`Type as Trait, indicating that we want`, indicating that we want
Trait`Trait’s version of`’s version of method`methodto be called here. The` to be called here. The as Trait`as Trait` part is
optional if it’s not ambiguous. Same with the angle brackets, hence the
shorter form.
Here’s an example of using the longer form.
fn main() { trait Foo { fn clone(&self); } #[derive(Clone)] struct Bar; impl Foo for Bar { fn clone(&self) { println!("Making a clone of Bar"); <Bar as Clone>::clone(self); } } }trait Foo { fn clone(&self); } #[derive(Clone)] struct Bar; impl Foo for Bar { fn clone(&self) { println!("Making a clone of Bar"); <Bar as Clone>::clone(self); } }
This will call the Clone`Clonetrait’s` trait’s clone()`clone()method, rather than` method, rather than Foo`Foo`’s.