We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Generics and Traits step 3 of 24
Trait bounds and why f64 is not Ord
Correct the trait bound on max_of so the supplied implementation works for
both integers and floating-point values. Keep its reduction and the
extremes wrapper unchanged.
pub fn max_of<T: PartialOrd + Copy>(items: &[T]) -> Option<T>
pub fn extremes(ints: Vec<i64>, floats: Vec<f64>) -> (Option<i64>, Option<f64>)
extremes calls the same generic function for each input vector. For this
exercise's integers and non-NaN floats, return the largest value from each
vector, or None when that vector is empty.
| Integers | Floats | Result |
|---|---|---|
[3, 9, 2] |
[1.5, 0.25, 7.75] |
(Some(9), Some(7.75)) |
[] |
[-2.5] |
(None, Some(-2.5)) |
[-5, -1, -9] |
[] |
(Some(-1), None) |
Each vector is independent. Do not substitute zero for an empty vector or use it as the initial maximum: that would also give the wrong answer for inputs containing only negative values.
Ask for the capabilities the body uses
The body borrows the slice, copies each element, then reduces the values:
items.iter().copied().reduce(|best, x| if x > best { x } else { best })
PartialOrd permits the > comparison. Copy lets .copied() turn each
&T into an owned T without moving it out of the borrowed slice. The trait
bounds describe what the generic body may rely on; callers must satisfy them.
reduce uses the first element as its initial candidate and returns None
for an empty iterator. Each later element replaces the candidate only when
it is strictly greater. Equal values keep the earlier candidate, so the
function preserves the first maximum.
Why the starter rejects f64
The starter requires T: Ord + Copy. That works for i64, but the call with
floats fails because f64 does not implement Ord. Read the diagnostic's
unmet bound and the note pointing to the function signature.
Ord requires a total ordering consistent with equality. Ordinary floating
comparisons include unordered cases: NaN is neither less than, greater than,
nor equal to 1.0, and is not even equal to itself. f64 implements
PartialOrd, whose partial_cmp can return None for incomparable values.
This does not mean floats cannot be given a total order. f64::total_cmp
provides an explicit ordering policy, including NaNs and signed zero. That
policy differs from ordinary float equality and comparison, so using it is a
separate choice rather than an Ord implementation on f64.
The limit of this reduction
The exercise inputs exclude NaN. More generally, a PartialOrd bound does
not promise that every pair is comparable. In this reduction, an incomparable
comparison makes x > best false, so the current candidate is retained.
For example, an initial NaN would remain the result, while a later NaN would
be skipped when the current candidate is a number.
Treat this as a defined selection rule, not a guarantee of a greatest element for every possible partially ordered type. Choosing how to handle unordered values belongs in the contract of any broader API you build.
Keep both bounds
Removing Copy breaks the existing .copied() call. Removing the ordering
bound makes the generic > comparison invalid. The fix here is to relax
Ord to PartialOrd while retaining Copy, not to add conversions, clone
the input vector or duplicate the integer and float implementations.
The harness represents None as JSON null. The solution must compile,
return the expected values and pass clippy -D warnings.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.