]> git.proxmox.com Git - rustc.git/blame - src/doc/rust-by-example/src/generics/assoc_items/the_problem.md
New upstream version 1.35.0+dfsg1
[rustc.git] / src / doc / rust-by-example / src / generics / assoc_items / the_problem.md
CommitLineData
2c00a5a8
XL
1# The Problem
2
3A `trait` that is generic over its container type has type specification
4requirements - users of the `trait` *must* specify all of its generic types.
5
6In the example below, the `Contains` `trait` allows the use of the generic
7types `A` and `B`. The trait is then implemented for the `Container` type,
8specifying `i32` for `A` and `B` so that it can be used with `fn difference()`.
9
10Because `Contains` is generic, we are forced to explicitly state *all* of the
11generic types for `fn difference()`. In practice, we want a way to express that
12`A` and `B` are determined by the *input* `C`. As you will see in the next
13section, associated types provide exactly that capability.
14
15```rust,editable
16struct Container(i32, i32);
17
18// A trait which checks if 2 items are stored inside of container.
19// Also retrieves first or last value.
20trait Contains<A, B> {
532ac7d7 21 fn contains(&self, _: &A, _: &B) -> bool; // Explicitly requires `A` and `B`.
2c00a5a8
XL
22 fn first(&self) -> i32; // Doesn't explicitly require `A` or `B`.
23 fn last(&self) -> i32; // Doesn't explicitly require `A` or `B`.
24}
25
26impl Contains<i32, i32> for Container {
27 // True if the numbers stored are equal.
28 fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
29 (&self.0 == number_1) && (&self.1 == number_2)
30 }
31
32 // Grab the first number.
33 fn first(&self) -> i32 { self.0 }
34
35 // Grab the last number.
36 fn last(&self) -> i32 { self.1 }
37}
38
39// `C` contains `A` and `B`. In light of that, having to express `A` and
40// `B` again is a nuisance.
41fn difference<A, B, C>(container: &C) -> i32 where
42 C: Contains<A, B> {
43 container.last() - container.first()
44}
45
46fn main() {
47 let number_1 = 3;
48 let number_2 = 10;
49
50 let container = Container(number_1, number_2);
51
52 println!("Does container contain {} and {}: {}",
53 &number_1, &number_2,
54 container.contains(&number_1, &number_2));
55 println!("First number: {}", container.first());
56 println!("Last number: {}", container.last());
57
58 println!("The difference is: {}", difference(&container));
59}
60```
61
62### See also:
63
64[`struct`s][structs], and [`trait`s][traits]
65
66[structs]: custom_types/structs.html
67[traits]: trait.html