]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/items/traits.md
New upstream version 1.22.1+dfsg1
[rustc.git] / src / doc / reference / src / items / traits.md
1 # Traits
2
3 A _trait_ describes an abstract interface that types can implement. This
4 interface consists of associated items, which come in three varieties:
5
6 - [functions](#associated-functions-and-methods)
7 - [types](#associated-types)
8 - [constants](#associated-constants)
9
10 All traits define an implicit type parameter `Self` that refers to "the type
11 that is implementing this interface". Traits may also contain additional type
12 parameters. These type parameters (including `Self`) may be constrained by
13 other traits and so forth as usual.
14
15 Traits are implemented for specific types through separate [implementations].
16
17 ## Associated functions and methods
18
19 Associated functions whose first parameter is named `self` are called methods
20 and may be invoked using `.` notation (e.g., `x.foo()`) as well as the usual
21 function call notation (`foo(x)`).
22
23 Consider the following trait:
24
25 ```rust
26 # type Surface = i32;
27 # type BoundingBox = i32;
28 trait Shape {
29 fn draw(&self, Surface);
30 fn bounding_box(&self) -> BoundingBox;
31 }
32 ```
33
34 This defines a trait with two methods. All values that have [implementations]
35 of this trait in scope can have their `draw` and `bounding_box` methods called,
36 using `value.bounding_box()` [syntax]. Note that `&self` is short for `self:
37 &Self`, and similarly, `self` is short for `self: Self` and `&mut self` is
38 short for `self: &mut Self`.
39
40 [trait object]: types.html#trait-objects
41 [implementations]: items/implementations.html
42 [syntax]: expressions/method-call-expr.html
43
44 Traits can include default implementations of methods, as in:
45
46 ```rust
47 trait Foo {
48 fn bar(&self);
49 fn baz(&self) { println!("We called baz."); }
50 }
51 ```
52
53 Here the `baz` method has a default implementation, so types that implement
54 `Foo` need only implement `bar`. It is also possible for implementing types to
55 override a method that has a default implementation.
56
57 Type parameters can be specified for a trait to make it generic. These appear
58 after the trait name, using the same syntax used in [generic
59 functions](items/functions.html#generic-functions).
60
61 ```rust
62 trait Seq<T> {
63 fn len(&self) -> u32;
64 fn elt_at(&self, n: u32) -> T;
65 fn iter<F>(&self, F) where F: Fn(T);
66 }
67 ```
68
69 Associated functions may lack a `self` argument, sometimes called 'static
70 methods'. This means that they can only be called with function call syntax
71 (`f(x)`) and not method call syntax (`obj.f()`). The way to refer to the name
72 of a static method is to qualify it with the trait name or type name, treating
73 the trait name like a module. For example:
74
75 ```rust
76 trait Num {
77 fn from_i32(n: i32) -> Self;
78 }
79 impl Num for f64 {
80 fn from_i32(n: i32) -> f64 { n as f64 }
81 }
82 let x: f64 = Num::from_i32(42);
83 let x: f64 = f64::from_i32(42);
84 ```
85
86 ## Associated Types
87
88 It is also possible to define associated types for a trait. Consider the
89 following example of a `Container` trait. Notice how the type is available for
90 use in the method signatures:
91
92 ```rust
93 trait Container {
94 type E;
95 fn empty() -> Self;
96 fn insert(&mut self, Self::E);
97 }
98 ```
99
100 In order for a type to implement this trait, it must not only provide
101 implementations for every method, but it must specify the type `E`. Here's an
102 implementation of `Container` for the standard library type `Vec`:
103
104 ```rust
105 # trait Container {
106 # type E;
107 # fn empty() -> Self;
108 # fn insert(&mut self, Self::E);
109 # }
110 impl<T> Container for Vec<T> {
111 type E = T;
112 fn empty() -> Vec<T> { Vec::new() }
113 fn insert(&mut self, x: T) { self.push(x); }
114 }
115 ```
116
117 ## Associated Constants
118
119 A trait can define constants like this:
120
121 ```rust
122 trait Foo {
123 const ID: i32;
124 }
125
126 impl Foo for i32 {
127 const ID: i32 = 1;
128 }
129
130 fn main() {
131 assert_eq!(1, i32::ID);
132 }
133 ```
134
135 Any implementor of `Foo` will have to define `ID`. Without the definition:
136
137 ```rust,compile_fail,E0046
138 trait Foo {
139 const ID: i32;
140 }
141
142 impl Foo for i32 {
143 }
144 ```
145
146 gives
147
148 ```text
149 error: not all trait items implemented, missing: `ID` [E0046]
150 impl Foo for i32 {
151 }
152 ```
153
154 A default value can be implemented as well:
155
156 ```rust
157 trait Foo {
158 const ID: i32 = 1;
159 }
160
161 impl Foo for i32 {
162 }
163
164 impl Foo for i64 {
165 const ID: i32 = 5;
166 }
167
168 fn main() {
169 assert_eq!(1, i32::ID);
170 assert_eq!(5, i64::ID);
171 }
172 ```
173
174 As you can see, when implementing `Foo`, you can leave it unimplemented, as
175 with `i32`. It will then use the default value. But, as in `i64`, we can also
176 add our own definition.
177
178 Associated constants don’t have to be associated with a trait. An `impl` block
179 for a `struct` or an `enum` works fine too:
180
181 ```rust
182 struct Foo;
183
184 impl Foo {
185 const FOO: u32 = 3;
186 }
187 ```
188
189 ## Trait bounds
190
191 Generic functions may use traits as _bounds_ on their type parameters. This
192 will have three effects:
193
194 - Only types that have the trait may instantiate the parameter.
195 - Within the generic function, the methods of the trait can be called on values
196 that have the parameter's type. Associated types can be used in the
197 function's signature, and associated constants can be used in expressions
198 within the function body.
199 - Generic functions and types with the same or weaker bounds can use the
200 generic type in the function body or signature.
201
202 For example:
203
204 ```rust
205 # type Surface = i32;
206 # trait Shape { fn draw(&self, Surface); }
207 struct Figure<S: Shape>(S, S);
208 fn draw_twice<T: Shape>(surface: Surface, sh: T) {
209 sh.draw(surface);
210 sh.draw(surface);
211 }
212 fn draw_figure<U: Shape>(surface: Surface, Figure(sh1, sh2): Figure<U>) {
213 sh1.draw(surface);
214 draw_twice(surface, sh2); // Can call this since U: Shape
215 }
216 ```
217
218 ## Trait objects
219
220 Traits also define a [trait object] with the same name as the trait. Values of
221 this type are created by coercing from a pointer of some specific type to a
222 pointer of trait type. For example, `&T` could be coerced to `&Shape` if `T:
223 Shape` holds (and similarly for `Box<T>`). This coercion can either be implicit
224 or [explicit]. Here is an example of an explicit coercion:
225
226 [trait object]: types.html#trait-objects
227 [explicit]: expressions/operator-expr.html#type-cast-expressions
228
229 ```rust
230 trait Shape { }
231 impl Shape for i32 { }
232 let mycircle = 0i32;
233 let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
234 ```
235
236 The resulting value is a box containing the value that was cast, along with
237 information that identifies the methods of the implementation that was used.
238 Values with a trait type can have [methods called] on them, for any method in
239 the trait, and can be used to instantiate type parameters that are bounded by
240 the trait.
241
242 [methods called]: expressions/method-call-expr.html
243
244 ## Supertraits
245
246 Trait bounds on `Self` are considered "supertraits". These are required to be
247 acyclic. Supertraits are somewhat different from other constraints in that
248 they affect what methods are available in the vtable when the trait is used as
249 a [trait object]. Consider the following example:
250
251 ```rust
252 trait Shape { fn area(&self) -> f64; }
253 trait Circle : Shape { fn radius(&self) -> f64; }
254 ```
255
256 The syntax `Circle : Shape` means that types that implement `Circle` must also
257 have an implementation for `Shape`. Multiple supertraits are separated by `+`,
258 `trait Circle : Shape + PartialEq { }`. In an implementation of `Circle` for a
259 given type `T`, methods can refer to `Shape` methods, since the typechecker
260 checks that any type with an implementation of `Circle` also has an
261 implementation of `Shape`:
262
263 ```rust
264 struct Foo;
265
266 trait Shape { fn area(&self) -> f64; }
267 trait Circle : Shape { fn radius(&self) -> f64; }
268 impl Shape for Foo {
269 fn area(&self) -> f64 {
270 0.0
271 }
272 }
273 impl Circle for Foo {
274 fn radius(&self) -> f64 {
275 println!("calling area: {}", self.area());
276
277 0.0
278 }
279 }
280
281 let c = Foo;
282 c.radius();
283 ```
284
285 In type-parameterized functions, methods of the supertrait may be called on
286 values of subtrait-bound type parameters. Referring to the previous example of
287 `trait Circle : Shape`:
288
289 ```rust
290 # trait Shape { fn area(&self) -> f64; }
291 # trait Circle : Shape { fn radius(&self) -> f64; }
292 fn radius_times_area<T: Circle>(c: T) -> f64 {
293 // `c` is both a Circle and a Shape
294 c.radius() * c.area()
295 }
296 ```
297
298 Likewise, supertrait methods may also be called on trait objects.
299
300 ```rust
301 # trait Shape { fn area(&self) -> f64; }
302 # trait Circle : Shape { fn radius(&self) -> f64; }
303 # impl Shape for i32 { fn area(&self) -> f64 { 0.0 } }
304 # impl Circle for i32 { fn radius(&self) -> f64 { 0.0 } }
305 # let mycircle = 0i32;
306 let mycircle = Box::new(mycircle) as Box<Circle>;
307 let nonsense = mycircle.radius() * mycircle.area();
308 ```