3 A _trait_ describes an abstract interface that types can implement. This
4 interface consists of associated items, which come in three varieties:
6 - [functions](#associated-functions-and-methods)
7 - [types](#associated-types)
8 - [constants](#associated-constants)
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.
15 Traits are implemented for specific types through separate [implementations].
17 ## Associated functions and methods
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)`).
23 Consider the following trait:
27 # type BoundingBox = i32;
29 fn draw(&self, Surface);
30 fn bounding_box(&self) -> BoundingBox;
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`.
40 [trait object]: types.html#trait-objects
41 [implementations]: items/implementations.html
42 [syntax]: expressions/method-call-expr.html
44 Traits can include default implementations of methods, as in:
49 fn baz(&self) { println!("We called baz."); }
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.
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).
64 fn elt_at(&self, n: u32) -> T;
65 fn iter<F>(&self, F) where F: Fn(T);
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:
77 fn from_i32(n: i32) -> Self;
80 fn from_i32(n: i32) -> f64 { n as f64 }
82 let x: f64 = Num::from_i32(42);
83 let x: f64 = f64::from_i32(42);
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:
96 fn insert(&mut self, Self::E);
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`:
107 # fn empty() -> Self;
108 # fn insert(&mut self, Self::E);
110 impl<T> Container for Vec<T> {
112 fn empty() -> Vec<T> { Vec::new() }
113 fn insert(&mut self, x: T) { self.push(x); }
117 ## Associated Constants
119 A trait can define constants like this:
131 assert_eq!(1, i32::ID);
135 Any implementor of `Foo` will have to define `ID`. Without the definition:
137 ```rust,compile_fail,E0046
149 error: not all trait items implemented, missing: `ID` [E0046]
154 A default value can be implemented as well:
169 assert_eq!(1, i32::ID);
170 assert_eq!(5, i64::ID);
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.
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:
191 Generic functions may use traits as _bounds_ on their type parameters. This
192 will have three effects:
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.
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) {
212 fn draw_figure<U: Shape>(surface: Surface, Figure(sh1, sh2): Figure<U>) {
214 draw_twice(surface, sh2); // Can call this since U: Shape
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:
226 [trait object]: types.html#trait-objects
227 [explicit]: expressions/operator-expr.html#type-cast-expressions
231 impl Shape for i32 { }
233 let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
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
242 [methods called]: expressions/method-call-expr.html
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:
252 trait Shape { fn area(&self) -> f64; }
253 trait Circle : Shape { fn radius(&self) -> f64; }
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`:
266 trait Shape { fn area(&self) -> f64; }
267 trait Circle : Shape { fn radius(&self) -> f64; }
269 fn area(&self) -> f64 {
273 impl Circle for Foo {
274 fn radius(&self) -> f64 {
275 println!("calling area: {}", self.area());
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`:
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()
298 Likewise, supertrait methods may also be called on trait objects.
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();