1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
% Universal Function Call Syntax
Sometimes, functions can have the same names. Consider this code:
```rust
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()`, we’d get an error:
```text
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:
```rust
# 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);
```
Let’s break it down.
```rust,ignore
Foo::
Bar::
```
These halves of the invocation are the types of the two traits: `Foo` and
`Bar`. This is what ends up actually doing the disambiguation between the two:
Rust calls the one from the trait name you use.
```rust,ignore
f(&b)
```
When we call a method like `b.f()` using [method syntax][methodsyntax], Rust
will automatically borrow `b` if `f()` takes `&self`. In this case, Rust will
not, and so we need to pass an explicit `&b`.
[methodsyntax]: method-syntax.html
# Angle-bracket Form
The form of UFCS we just talked about:
```rust,ignore
Trait::method(args);
```
Is a short-hand. There’s an expanded form of this that’s needed in some
situations:
```rust,ignore
<Type as Trait>::method(args);
```
The `<>::` syntax is a means of providing a type hint. The type goes inside
the `<>`s. In this case, the type is `Type as Trait`, indicating that we want
`Trait`’s version of `method` to be called here. The `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.
```rust
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` trait’s `clone()` method, rather than `Foo`’s.
|