From 816ab35bec9dec1571988fcf97e57a38a32f5ff5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 10 Jun 2015 08:59:45 +0200 Subject: [PATCH 1/1] defer refrences until later; introduce testing in part03 --- src/part01.rs | 12 +++--------- src/part02.rs | 5 ++--- src/part03.rs | 35 ++++++++++++++++++++++++----------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/part01.rs b/src/part01.rs index 927a617..d046a1b 100644 --- a/src/part01.rs +++ b/src/part01.rs @@ -34,16 +34,10 @@ fn number_or_default(n: NumberOrNothing, default: i32) -> i32 { } } -// With this fresh knowledge, let us now refactor `vec_min`. First of all, we are doing a small change -// to the type: `&Vec` denotes a *reference* to a `Vec`. You can think of this as a pointer -// (in C terms): Arguments in Rust are passed *by value*, so we need to employ explicit references if -// that's not what we want. References are per default immutable (like variables), a mutable reference -// would be denoted `&mut Vec`. -fn vec_min(v: &Vec) -> NumberOrNothing { +// With this fresh knowledge, let us now refactor `vec_min`. +fn vec_min(v: Vec) -> NumberOrNothing { let mut min = Nothing; for e in v { - // Now that `v` is just a reference, the same goes for `e`, so we have to dereference the pointer. - let e = *e; // Notice that all we do here is compute a new value for `min`, and that it will always end // up being a `Number` rather than `Nothing`. In Rust, the structure of the code // can express this uniformity. @@ -87,7 +81,7 @@ fn read_vec() -> Vec { } pub fn part_main() { let vec = read_vec(); - let min = vec_min(&vec); + let min = vec_min(vec); min.print(); } // You will have to replace `part00` by `part01` in the `main` function in diff --git a/src/part02.rs b/src/part02.rs index 7261f19..4e0fa6b 100644 --- a/src/part02.rs +++ b/src/part02.rs @@ -78,10 +78,9 @@ trait Minimum : Copy { // we cannot call `min`. Just try it! There is no reason to believe that `T` provides such an operation. // This is in strong contrast to C++, where the compiler only checks such details when the // function is actually used. -fn vec_min(v: &Vec) -> SomethingOrNothing { +fn vec_min(v: Vec) -> SomethingOrNothing { let mut min = Nothing; for e in v { - let e = *e; min = Something(match min { Nothing => e, Something(n) => T::min(n, e) @@ -125,7 +124,7 @@ fn read_vec() -> Vec { } pub fn part_main() { let vec = read_vec(); - let min = vec_min(&vec); + let min = vec_min(vec); min.print(); } diff --git a/src/part03.rs b/src/part03.rs index cb0807b..d4805e7 100644 --- a/src/part03.rs +++ b/src/part03.rs @@ -30,10 +30,9 @@ trait Minimum : Copy { fn min(a: Self, b: Self) -> Self; } -fn vec_min(v: &Vec) -> SomethingOrNothing { +fn vec_min(v: Vec) -> SomethingOrNothing { let mut min = Nothing; for e in v { - let e = *e; min = Something(match min { Nothing => e, Something(n) => T::min(n, e) @@ -48,20 +47,34 @@ impl Minimum for i32 { } } -use std::fmt; -impl fmt::Display for SomethingOrNothing { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl SomethingOrNothing { + fn print(self) { match self { - &Something(ref t) => t.fmt(f), - &Nothing => "Nothing".fmt(f), - } + Nothing => println!("The number is: "), + Something(n) => println!("The number is: {}", n), + }; } } - pub fn part_main() { let vec = read_vec(); - let min = vec_min(&vec); - println!("The minimum is: {}", min); + let min = vec_min(vec); + min.print(); +} + +impl SomethingOrNothing { + fn equals(self, other: Self) -> bool { + match (self, other) { + (Nothing , Nothing ) => true, + (Something(n), Something (m)) => n == m, + _ => false, + } + } +} + +#[test] +fn tes_vec_min() { + assert!(vec_min(vec![6,325,33,532,5,7]).equals(Something(5))); + assert!(vec_min(vec![]).equals(Nothing)); } // [index](main.html) | [previous](part02.html) | next -- 2.30.2