]>
Commit | Line | Data |
---|---|---|
ea8adc8c XL |
1 | # Traits |
2 | ||
0bf4aa26 XL |
3 | > **<sup>Syntax</sup>**\ |
4 | > _Trait_ :\ | |
5 | > `unsafe`<sup>?</sup> `trait` [IDENTIFIER] | |
6 | > [_Generics_]<sup>?</sup> | |
13cf67c4 | 7 | > ( `:` [_TypeParamBounds_]<sup>?</sup> )<sup>?</sup> |
0bf4aa26 XL |
8 | > [_WhereClause_]<sup>?</sup> `{`\ |
9 | > _TraitItem_<sup>\*</sup>\ | |
10 | > `}` | |
11 | > | |
12 | > _TraitItem_ :\ | |
60c5eb7d | 13 | > [_OuterAttribute_]<sup>\*</sup> [_Visibility_]<sup>?</sup> (\ |
13cf67c4 XL |
14 | > _TraitFunc_\ |
15 | > | _TraitMethod_\ | |
16 | > | _TraitConst_\ | |
17 | > | _TraitType_\ | |
18 | > | [_MacroInvocationSemi_]\ | |
19 | > ) | |
0bf4aa26 XL |
20 | > |
21 | > _TraitFunc_ :\ | |
22 | > _TraitFunctionDecl_ ( `;` | [_BlockExpression_] ) | |
23 | > | |
24 | > _TraitMethod_ :\ | |
25 | > _TraitMethodDecl_ ( `;` | [_BlockExpression_] ) | |
26 | > | |
27 | > _TraitFunctionDecl_ :\ | |
28 | > [_FunctionQualifiers_] `fn` [IDENTIFIER] [_Generics_]<sup>?</sup>\ | |
29 | > `(` _TraitFunctionParameters_<sup>?</sup> `)`\ | |
30 | > [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup> | |
31 | > | |
32 | > _TraitMethodDecl_ :\ | |
33 | > [_FunctionQualifiers_] `fn` [IDENTIFIER] [_Generics_]<sup>?</sup>\ | |
34 | > `(` [_SelfParam_] (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup> `)`\ | |
35 | > [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup> | |
36 | > | |
37 | > _TraitFunctionParameters_ :\ | |
38 | > _TraitFunctionParam_ (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup> | |
39 | > | |
40 | > _TraitFunctionParam_<sup>[†](#parameter-patterns)</sup> :\ | |
e74abb32 | 41 | > [_OuterAttribute_]<sup>\*</sup> ( [_Pattern_] `:` )<sup>?</sup> [_Type_] |
0bf4aa26 XL |
42 | > |
43 | > _TraitConst_ :\ | |
13cf67c4 | 44 | > `const` [IDENTIFIER] `:` [_Type_] ( `=` [_Expression_] )<sup>?</sup> `;` |
0bf4aa26 XL |
45 | > |
46 | > _TraitType_ :\ | |
13cf67c4 | 47 | > `type` [IDENTIFIER] ( `:` [_TypeParamBounds_]<sup>?</sup> )<sup>?</sup> `;` |
0bf4aa26 | 48 | |
ea8adc8c | 49 | A _trait_ describes an abstract interface that types can implement. This |
0531ce1d | 50 | interface consists of [associated items], which come in three varieties: |
ea8adc8c | 51 | |
416331ca XL |
52 | - [functions](associated-items.md#associated-functions-and-methods) |
53 | - [types](associated-items.md#associated-types) | |
54 | - [constants](associated-items.md#associated-constants) | |
ea8adc8c XL |
55 | |
56 | All traits define an implicit type parameter `Self` that refers to "the type | |
57 | that is implementing this interface". Traits may also contain additional type | |
94b46f34 XL |
58 | parameters. These type parameters, including `Self`, may be constrained by |
59 | other traits and so forth [as usual][generics]. | |
ea8adc8c XL |
60 | |
61 | Traits are implemented for specific types through separate [implementations]. | |
62 | ||
83c7162d XL |
63 | Items associated with a trait do not need to be defined in the trait, but they |
64 | may be. If the trait provides a definition, then this definition acts as a | |
65 | default for any implementation which does not override it. If it does not, then | |
66 | any implementation must provide a definition. | |
67 | ||
ea8adc8c XL |
68 | ## Trait bounds |
69 | ||
94b46f34 | 70 | Generic items may use traits as [bounds] on their type parameters. |
ea8adc8c | 71 | |
0531ce1d XL |
72 | ## Generic Traits |
73 | ||
74 | Type parameters can be specified for a trait to make it generic. These appear | |
94b46f34 | 75 | after the trait name, using the same syntax used in [generic functions]. |
0531ce1d XL |
76 | |
77 | ```rust | |
78 | trait Seq<T> { | |
79 | fn len(&self) -> u32; | |
80 | fn elt_at(&self, n: u32) -> T; | |
0bf4aa26 | 81 | fn iter<F>(&self, f: F) where F: Fn(T); |
0531ce1d XL |
82 | } |
83 | ``` | |
84 | ||
ff7c6d11 | 85 | ## Object Safety |
ea8adc8c | 86 | |
ff7c6d11 XL |
87 | Object safe traits can be the base trait of a [trait object]. A trait is |
88 | *object safe* if it has the following qualities (defined in [RFC 255]): | |
ea8adc8c | 89 | |
ff7c6d11 | 90 | * It must not require `Self: Sized` |
83c7162d XL |
91 | * All associated functions must either have a `where Self: Sized` bound, or |
92 | * Not have any type parameters (although lifetime parameters are allowed), | |
93 | and | |
94 | * Be a [method] that does not use `Self` except in the type of the receiver. | |
ff7c6d11 | 95 | * It must not have any associated constants. |
94b46f34 | 96 | * All supertraits must also be object safe. |
ea8adc8c XL |
97 | |
98 | ## Supertraits | |
99 | ||
94b46f34 | 100 | **Supertraits** are traits that are required to be implemented for a type to |
b7449926 | 101 | implement a specific trait. Furthermore, anywhere a [generic][generics] or [trait object] |
94b46f34 XL |
102 | is bounded by a trait, it has access to the associated items of its supertraits. |
103 | ||
104 | Supertraits are declared by trait bounds on the `Self` type of a trait and | |
105 | transitively the supertraits of the traits declared in those trait bounds. It is | |
106 | an error for a trait to be its own supertrait. | |
107 | ||
108 | The trait with a supertrait is called a **subtrait** of its supertrait. | |
109 | ||
110 | The following is an example of declaring `Shape` to be a supertrait of `Circle`. | |
ea8adc8c XL |
111 | |
112 | ```rust | |
113 | trait Shape { fn area(&self) -> f64; } | |
114 | trait Circle : Shape { fn radius(&self) -> f64; } | |
115 | ``` | |
116 | ||
94b46f34 | 117 | And the following is the same example, except using [where clauses]. |
ea8adc8c XL |
118 | |
119 | ```rust | |
ea8adc8c | 120 | trait Shape { fn area(&self) -> f64; } |
94b46f34 XL |
121 | trait Circle where Self: Shape { fn radius(&self) -> f64; } |
122 | ``` | |
ea8adc8c | 123 | |
94b46f34 XL |
124 | This next example gives `radius` a default implementation using the `area` |
125 | function from `Shape`. | |
126 | ||
127 | ```rust | |
128 | # trait Shape { fn area(&self) -> f64; } | |
129 | trait Circle where Self: Shape { | |
130 | fn radius(&self) -> f64 { | |
131 | // A = pi * r^2 | |
132 | // so algebraically, | |
133 | // r = sqrt(A / pi) | |
134 | (self.area() /std::f64::consts::PI).sqrt() | |
ea8adc8c XL |
135 | } |
136 | } | |
ea8adc8c XL |
137 | ``` |
138 | ||
94b46f34 | 139 | This next example calls a supertrait method on a generic parameter. |
ea8adc8c XL |
140 | |
141 | ```rust | |
142 | # trait Shape { fn area(&self) -> f64; } | |
143 | # trait Circle : Shape { fn radius(&self) -> f64; } | |
94b46f34 XL |
144 | fn print_area_and_radius<C: Circle>(c: C) { |
145 | // Here we call the area method from the supertrait `Shape` of `Circle`. | |
146 | println!("Area: {}", c.area()); | |
147 | println!("Radius: {}", c.radius()); | |
ea8adc8c XL |
148 | } |
149 | ``` | |
150 | ||
94b46f34 | 151 | Similarly, here is an example of calling supertrait methods on trait objects. |
ea8adc8c XL |
152 | |
153 | ```rust | |
154 | # trait Shape { fn area(&self) -> f64; } | |
155 | # trait Circle : Shape { fn radius(&self) -> f64; } | |
94b46f34 XL |
156 | # struct UnitCircle; |
157 | # impl Shape for UnitCircle { fn area(&self) -> f64 { std::f64::consts::PI } } | |
158 | # impl Circle for UnitCircle { fn radius(&self) -> f64 { 1.0 } } | |
159 | # let circle = UnitCircle; | |
160 | let circle = Box::new(circle) as Box<dyn Circle>; | |
161 | let nonsense = circle.radius() * circle.area(); | |
ea8adc8c | 162 | ``` |
ff7c6d11 | 163 | |
0bf4aa26 XL |
164 | ## Unsafe traits |
165 | ||
166 | Traits items that begin with the `unsafe` keyword indicate that *implementing* the | |
167 | trait may be [unsafe]. It is safe to use a correctly implemented unsafe trait. | |
168 | The [trait implementation] must also begin with the `unsafe` keyword. | |
169 | ||
170 | [`Sync`] and [`Send`] are examples of unsafe traits. | |
171 | ||
172 | ## Parameter patterns | |
173 | ||
174 | Function or method declarations without a body only allow [IDENTIFIER] or | |
175 | `_` [wild card][WildcardPattern] patterns. `mut` [IDENTIFIER] is currently | |
176 | allowed, but it is deprecated and will become a hard error in the future. | |
177 | <!-- https://github.com/rust-lang/rust/issues/35203 --> | |
178 | ||
179 | In the 2015 edition, the pattern for a trait function or method parameter is | |
180 | optional: | |
181 | ||
182 | ```rust | |
183 | trait T { | |
184 | fn f(i32); // Parameter identifiers are not required. | |
185 | } | |
186 | ``` | |
187 | ||
188 | The kinds of patterns for parameters is limited to one of the following: | |
189 | ||
190 | * [IDENTIFIER] | |
191 | * `mut` [IDENTIFIER] | |
192 | * [`_`][WildcardPattern] | |
193 | * `&` [IDENTIFIER] | |
194 | * `&&` [IDENTIFIER] | |
195 | ||
196 | Beginning in the 2018 edition, function or method parameter patterns are no | |
197 | longer optional. Also, all irrefutable patterns are allowed as long as there | |
198 | is a body. Without a body, the limitations listed above are still in effect. | |
199 | ||
200 | ```rust,edition2018 | |
201 | trait T { | |
202 | fn f1((a, b): (i32, i32)) {} | |
203 | fn f2(_: (i32, i32)); // Cannot use tuple pattern without a body. | |
204 | } | |
205 | ``` | |
206 | ||
60c5eb7d XL |
207 | ## Item visibility |
208 | ||
209 | Trait items syntactically allow a [_Visibility_] annotation, but this is | |
210 | rejected when the trait is validated. This allows items to be parsed with a | |
211 | unified syntax across different contexts where they are used. As an example, | |
212 | an empty `vis` macro fragment specifier can be used for trait items, where the | |
213 | macro rule may be used in other situations where visibility is allowed. | |
214 | ||
215 | ```rust | |
216 | macro_rules! create_method { | |
217 | ($vis:vis $name:ident) => { | |
218 | $vis fn $name(&self) {} | |
219 | }; | |
220 | } | |
221 | ||
222 | trait T1 { | |
223 | // Empty `vis` is allowed. | |
224 | create_method! { method_of_t1 } | |
225 | } | |
226 | ||
227 | struct S; | |
228 | ||
229 | impl S { | |
230 | // Visibility is allowed here. | |
231 | create_method! { pub method_of_s } | |
232 | } | |
233 | ||
234 | impl T1 for S {} | |
235 | ||
236 | fn main() { | |
237 | let s = S; | |
238 | s.method_of_t1(); | |
239 | s.method_of_s(); | |
240 | } | |
241 | ``` | |
242 | ||
416331ca XL |
243 | [IDENTIFIER]: ../identifiers.md |
244 | [WildcardPattern]: ../patterns.md#wildcard-pattern | |
245 | [_BlockExpression_]: ../expressions/block-expr.md | |
246 | [_Expression_]: ../expressions.md | |
247 | [_FunctionQualifiers_]: functions.md | |
248 | [_FunctionReturnType_]: functions.md | |
249 | [_Generics_]: generics.md | |
250 | [_MacroInvocationSemi_]: ../macros.md#macro-invocation | |
251 | [_OuterAttribute_]: ../attributes.md | |
252 | [_Pattern_]: ../patterns.md | |
253 | [_SelfParam_]: associated-items.md#methods | |
254 | [_TypeParamBounds_]: ../trait-bounds.md | |
255 | [_Type_]: ../types.md#type-expressions | |
60c5eb7d | 256 | [_Visibility_]: ../visibility-and-privacy.md |
416331ca XL |
257 | [_WhereClause_]: generics.md#where-clauses |
258 | [bounds]: ../trait-bounds.md | |
259 | [trait object]: ../types/trait-object.md | |
0531ce1d | 260 | [RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md |
416331ca XL |
261 | [associated items]: associated-items.md |
262 | [method]: associated-items.md#methods | |
263 | [implementations]: implementations.md | |
264 | [generics]: generics.md | |
265 | [where clauses]: generics.md#where-clauses | |
266 | [generic functions]: functions.md#generic-functions | |
267 | [unsafe]: ../unsafety.md | |
268 | [trait implementation]: implementations.md#trait-implementations | |
269 | [`Send`]: ../special-types-and-traits.md#send | |
270 | [`Sync`]: ../special-types-and-traits.md#sync |