Skip to content

Commit e2e3652

Browse files
Merge pull request #214 from Havvy/assoc-items
Move associated items to their own page.
2 parents 1176a6c + bf9ba61 commit e2e3652

File tree

5 files changed

+306
-182
lines changed

5 files changed

+306
-182
lines changed

src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
- [Traits](items/traits.md)
3535
- [Implementations](items/implementations.md)
3636
- [External blocks](items/external-blocks.md)
37+
- [Associated Items](items/associated-items.md)
3738
- [Visibility and Privacy](visibility-and-privacy.md)
3839
- [Attributes](attributes.md)
3940

src/items/associated-items.md

+280
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# Associated Items
2+
3+
*Associated Items* are the items declared in [traits] or defined in
4+
[implementations]. They are called this because they are defined on an associate
5+
type — the type in the implementation. They are a subset of the kinds of
6+
items you can declare in a module. Specifically, there are [associated
7+
functions] (including methods), [associated types], and [associated constants].
8+
9+
[associated functions]: #associated-functions-and-methods
10+
[associated types]: #associated-types
11+
[associated constants]: #associated-constants
12+
13+
Associated items are useful when the associated item logically is related to the
14+
associating item. For example, the `is_some` method on `Option` is intrinsically
15+
related to Options, so should be associated.
16+
17+
Every associated item kind comes in two varieties: definitions that contain the
18+
actual implementation and declarations that declare signatures for
19+
definitions.
20+
21+
It is the declarations that make up the contract of traits and what it available
22+
on generic types.
23+
24+
## Associated functions and methods
25+
26+
*Associated functions* are [functions] associated with a type.
27+
28+
An *associated function declaration* declares a signature for an associated
29+
function definition. It is written as a function item, except the
30+
function body is replaced with a `;`.
31+
32+
The identifier if the name of the function. The generics, parameter list,
33+
return type, and where clause of the associated function must be the same as the
34+
associated function declarations's.
35+
36+
An *associated function definiton* defines a function associated with another
37+
type. It is written the same as a [function item].
38+
39+
An example of a common associated function is a `new` function that returns
40+
a value of the type the associated function is associated with.
41+
42+
```rust
43+
struct Struct {
44+
field: i32
45+
}
46+
47+
impl Struct {
48+
fn new() -> Struct {
49+
Struct {
50+
field: 0i32
51+
}
52+
}
53+
}
54+
55+
fn main () {
56+
let _struct = Struct::new();
57+
}
58+
```
59+
60+
When the associated function is declared on a trait, the function can also be
61+
called with a [path] that is a path to the trait appended by the name of the
62+
trait. When this happens, it is substituted for `<_ as Trait>::function_name`.
63+
64+
```rust
65+
trait Num {
66+
fn from_i32(n: i32) -> Self;
67+
}
68+
69+
impl Num for f64 {
70+
fn from_i32(n: i32) -> f64 { n as f64 }
71+
}
72+
73+
// These 4 are all equivalent in this case.
74+
let _: f64 = Num::from_i32(42);
75+
let _: f64 = <_ as Num>::from_i32(42);
76+
let _: f64 = <f64 as Num>::from_i32(42);
77+
let _: f64 = f64::from_i32(42);
78+
```
79+
80+
Associated functions whose first parameter is named `self` are called *methods*
81+
and may be invoked using the [method call operator], for example, `x.foo()`, as
82+
well as the usual function call notation.
83+
84+
When the first parameter is named `self`, the following shorthands may be used.
85+
86+
* `self` -> `self: Self`
87+
* `&'lifetime self` -> `self: &'lifetime Self`
88+
* `&'lifetime mut self` -> `self: &'lifetime mut Self`
89+
90+
> Note: Lifetimes can be and usually are elided with this shorthand.
91+
92+
Consider the following trait:
93+
94+
```rust
95+
# type Surface = i32;
96+
# type BoundingBox = i32;
97+
trait Shape {
98+
fn draw(&self, Surface);
99+
fn bounding_box(&self) -> BoundingBox;
100+
}
101+
```
102+
103+
This defines a trait with two methods. All values that have [implementations]
104+
of this trait while the trait is in scope can have their `draw` and
105+
`bounding_box` methods called.
106+
107+
```rust
108+
# type Surface = i32;
109+
# type BoundingBox = i32;
110+
# trait Shape {
111+
# fn draw(&self, Surface);
112+
# fn bounding_box(&self) -> BoundingBox;
113+
# }
114+
115+
struct Circle {
116+
// ...
117+
}
118+
119+
impl Shape for Circle {
120+
// ...
121+
# fn draw(&self, _: Surface) {}
122+
# fn bounding_box(&self) -> BoundingBox { 0i32 }
123+
}
124+
125+
# impl Circle {
126+
# fn new() -> Circle { Circle{} }
127+
}
128+
129+
let circle_shape = Circle::new();
130+
let bounding_box = circle_shape.bounding_box();
131+
```
132+
133+
## Associated Types
134+
135+
*Associated types* are [type aliases] associated with another type. Associated
136+
types cannot be defined in [inherent implementations] nor can they be given a
137+
default implementation in traits.
138+
139+
An *associated type declaration* declares a signature for associated type
140+
definitions. It is written as `type`, then an [identifier], and
141+
finally an optional list of trait bounds.
142+
143+
The identifier is the name of the declared type alias. The optional trait bounds
144+
must be fulfilled by the implementations of the type alias.
145+
146+
An *associated type definition* defines a type alias on another type. It is
147+
written as `type`, then an [identifier], then an `=`, and finally a [type].
148+
149+
If a type `Item` has an associated type `Assoc` from a trait `Trait`, then
150+
`<Item as Trait>::Assoc` is a type that is an alias of the type specified in the
151+
associated type definition. Furthermore, if `Item` is a type parameter, then
152+
`Item::Assoc` can be used in type parameters.
153+
154+
```rust
155+
trait AssociatedType {
156+
// Associated type declaration
157+
type Assoc;
158+
}
159+
160+
struct Struct;
161+
162+
struct OtherStruct;
163+
164+
impl AssociatedType for Struct {
165+
// Associated type definition
166+
type Assoc = OtherStruct;
167+
}
168+
169+
impl OtherStruct {
170+
fn new() -> OtherStruct {
171+
OtherStruct
172+
}
173+
}
174+
175+
fn main() {
176+
// Usage of the associated type to refer to OtherStruct as <Struct as AssociatedType>::Assoc
177+
let _other_struct: OtherStruct = <Struct as AssociatedType>::Assoc::new();
178+
}
179+
```
180+
181+
### Associated Types Container Example
182+
183+
Consider the following example of a `Container` trait. Notice that the type is
184+
available for use in the method signatures:
185+
186+
```rust
187+
trait Container {
188+
type E;
189+
fn empty() -> Self;
190+
fn insert(&mut self, Self::E);
191+
}
192+
```
193+
194+
In order for a type to implement this trait, it must not only provide
195+
implementations for every method, but it must specify the type `E`. Here's an
196+
implementation of `Container` for the standard library type `Vec`:
197+
198+
```rust
199+
# trait Container {
200+
# type E;
201+
# fn empty() -> Self;
202+
# fn insert(&mut self, Self::E);
203+
# }
204+
impl<T> Container for Vec<T> {
205+
type E = T;
206+
fn empty() -> Vec<T> { Vec::new() }
207+
fn insert(&mut self, x: T) { self.push(x); }
208+
}
209+
```
210+
211+
## Associated Constants
212+
213+
*Associated constants* are [constants] associated with a type.
214+
215+
An *associated constant declaration* declares a signature for associated
216+
constant definitions. It is written as `const`, then an identifier,
217+
then `:`, then a type, finished by a `;`.
218+
219+
The identifier is the name of the constant used in the path. The type is the
220+
type that the definition has to implement.
221+
222+
An *associated constant definition* defines a constant associated with a
223+
type. It is written the same as a [constant item].
224+
225+
### Associated Constants Examples
226+
227+
A basic example:
228+
229+
```rust
230+
trait ConstantId {
231+
const ID: i32;
232+
}
233+
234+
struct Struct;
235+
236+
impl ConstantId for Struct {
237+
const ID: i32 = 1;
238+
}
239+
240+
fn main() {
241+
assert_eq!(1, Struct::ID);
242+
}
243+
```
244+
245+
Using default values:
246+
247+
```rust
248+
trait ConstantIdDefault {
249+
const ID: i32 = 1;
250+
}
251+
252+
struct Struct;
253+
struct OtherStruct;
254+
255+
impl ConstantIdDefault for Struct {}
256+
257+
impl ConstantIdDefault for OtherStruct {
258+
const ID: i32 = 5;
259+
}
260+
261+
fn main() {
262+
assert_eq!(1, Struct::ID);
263+
assert_eq!(5, OtherStruct::ID);
264+
}
265+
```
266+
267+
[trait]: items/traits.html
268+
[traits]: items/traits.html
269+
[type aliases]: items/type-aliases.html
270+
[inherent implementations]: items/implementations.html#inherent-implementations
271+
[identifier]: identifiers.html
272+
[trait object]: types.html#trait-objects
273+
[implementations]: items/implementations.html
274+
[type]: types.html
275+
[constants]: items/constant-items.html
276+
[constant item]: items/constant-items.html
277+
[functions]: items/functions.html
278+
[method call operator]: expressions/method-call-expr.html
279+
[block]: expressions/block-expr.html
280+
[path]: paths.html

src/items/functions.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ on completion.
1212
[type]: types.html
1313

1414
When referred to, a _function_ yields a first-class *value* of the
15-
corresponding zero-sized [*function item type*][function item type], which
15+
corresponding zero-sized [*function item type*], which
1616
when called evaluates to a direct call to the function.
1717

18-
[function item type]: types.html#function-item-types
18+
[*function item type*]: types.html#function-item-types
1919

2020
For example, this is a simple function:
2121
```rust

0 commit comments

Comments
 (0)