mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-03-29 09:00:45 +02:00
Simplify generic min exercise (#1900)
I was a bit dissatisfied with the test code for the generic min exercise. We were supposed to be testing that the student wrote the generic function correctly, but we only test their `min` function with one type. I rewrote the exercise to test against multiple types, which required that we use the regular `Ord` trait rather than a custom one. I tend to prefer using the real items from `std` when we can because it's a good way to get students familiar with the standard library. I also removed the custom `Citation` type since it wasn't really important to the exercise.
This commit is contained in:
parent
025fbffa99
commit
d0656ca90b
src/generics
@ -5,12 +5,21 @@ minutes: 10
|
||||
# Exercise: Generic `min`
|
||||
|
||||
In this short exercise, you will implement a generic `min` function that
|
||||
determines the minimum of two values, using a `LessThan` trait.
|
||||
determines the minimum of two values, using the [`Ord`] trait.
|
||||
|
||||
```rust,compile_fail
|
||||
{{#include exercise.rs:LessThan}}
|
||||
use std::cmp::Ordering;
|
||||
|
||||
// TODO: implement the `min` function used in `main`.
|
||||
|
||||
{{#include exercise.rs:main}}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
- Show students the [`Ord`] trait and [`Ordering`] enum.
|
||||
|
||||
</details>
|
||||
|
||||
[`Ord`]: https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html
|
||||
[`Ordering`]: https://doc.rust-lang.org/stable/std/cmp/enum.Ordering.html
|
||||
|
@ -13,46 +13,24 @@
|
||||
// limitations under the License.
|
||||
|
||||
// ANCHOR: solution
|
||||
// ANCHOR: LessThan
|
||||
trait LessThan {
|
||||
/// Return true if self is less than other.
|
||||
fn less_than(&self, other: &Self) -> bool;
|
||||
}
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
struct Citation {
|
||||
author: &'static str,
|
||||
year: u32,
|
||||
}
|
||||
|
||||
impl LessThan for Citation {
|
||||
fn less_than(&self, other: &Self) -> bool {
|
||||
if self.author < other.author {
|
||||
true
|
||||
} else if self.author > other.author {
|
||||
false
|
||||
} else {
|
||||
self.year < other.year
|
||||
}
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: LessThan
|
||||
|
||||
fn min<T: LessThan>(l: T, r: T) -> T {
|
||||
if l.less_than(&r) {
|
||||
l
|
||||
} else {
|
||||
r
|
||||
fn min<T: Ord>(l: T, r: T) -> T {
|
||||
match l.cmp(&r) {
|
||||
Ordering::Less | Ordering::Equal => l,
|
||||
Ordering::Greater => r,
|
||||
}
|
||||
}
|
||||
|
||||
// ANCHOR: main
|
||||
fn main() {
|
||||
let cit1 = Citation { author: "Shapiro", year: 2011 };
|
||||
let cit2 = Citation { author: "Baumann", year: 2010 };
|
||||
let cit3 = Citation { author: "Baumann", year: 2019 };
|
||||
debug_assert_eq!(min(cit1, cit2), cit2);
|
||||
debug_assert_eq!(min(cit2, cit3), cit2);
|
||||
debug_assert_eq!(min(cit1, cit3), cit3);
|
||||
assert_eq!(min(0, 10), 0);
|
||||
assert_eq!(min(500, 123), 123);
|
||||
|
||||
assert_eq!(min('a', 'z'), 'a');
|
||||
assert_eq!(min('7', '1'), '1');
|
||||
|
||||
assert_eq!(min("hello", "goodbye"), "goodbye");
|
||||
assert_eq!(min("bat", "armadillo"), "armadillo");
|
||||
}
|
||||
// ANCHOR_END: main
|
||||
|
Loading…
x
Reference in New Issue
Block a user