Merge pull request #5 from r0e/master
[rust-101.git] / workspace / src / part02.rs
1 // Rust-101, Part 02: Generic types, Traits
2 // ========================================
3
4
5 // ## Generic datatypes
6
7 pub enum SomethingOrNothing<T>  {
8     Something(T),
9     Nothing,
10 }
11 // Instead of writing out all the variants, we can also just import them all at once.
12 pub use self::SomethingOrNothing::*;
13 type NumberOrNothing = SomethingOrNothing<i32>;
14
15 // ## Generic `impl`, Static functions
16 // Inside an `impl`, `Self` refers to the type we are implementing things for. Here, it is
17 // an alias for `SomethingOrNothing<T>`.
18 impl<T> SomethingOrNothing<T> {
19     fn new(o: Option<T>) -> Self {
20         unimplemented!()
21     }
22
23     fn to_option(self) -> Option<T> {
24         unimplemented!()
25     }
26 }
27 // You can call static functions, and in particular constructors, as demonstrated in `call_constructor`.
28 fn call_constructor(x: i32) -> SomethingOrNothing<i32> {
29     SomethingOrNothing::new(Some(x))
30 }
31
32 // ## Traits
33
34 pub trait Minimum : Copy {
35     fn min(self, b: Self) -> Self;
36 }
37
38 pub fn vec_min<T: Minimum>(v: Vec<T>) -> SomethingOrNothing<T> {
39     let mut min = Nothing;
40     for e in v {
41         min = Something(match min {
42             Nothing => e,
43             // Here, we can now call the `min` function of the trait.
44             Something(n) => {
45                 unimplemented!()
46             }
47         });
48     }
49     min
50 }
51
52 // ## Trait implementations
53 // To make `vec_min` usable with a `Vec<i32>`, we implement the `Minimum` trait for `i32`.
54 impl Minimum for i32 {
55     fn min(self, b: Self) -> Self {
56         unimplemented!()
57     }
58 }
59
60 // We again provide a `print` function.
61 impl NumberOrNothing {
62     pub fn print(self) {
63         match self {
64             Nothing => println!("The number is: <nothing>"),
65             Something(n) => println!("The number is: {}", n),
66         };
67     }
68 }
69
70 // Now we are ready to run our new code. Remember to change `main.rs` appropriately.
71 fn read_vec() -> Vec<i32> {
72     vec![18,5,7,3,9,27]
73 }
74 pub fn main() {
75     let vec = read_vec();
76     let min = vec_min(vec);
77     min.print();
78 }
79
80
81 // **Exercise 02.1**: Change your program such that it computes the minimum of a `Vec<f32>` (where `f32` is the type
82 // of 32-bit floating-point numbers). You should not change `vec_min` in any way, obviously!
83