We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Generics and Traits step 4 of 24
where clauses and the bound you cannot write inline
These two signatures mean exactly the same thing:
pub fn summarise<T: Display>(items: Vec<T>) -> String
pub fn summarise<T>(items: Vec<T>) -> String
where
T: Display,
So where looks like a style preference for people who dislike long angle
brackets. It is not. where is strictly more expressive, and the reason
matters the first time you get stuck.
Inline bounds can only be attached to a type parameter — a name inside the
<...>. A where clause can constrain any type expression at all:
where
I: IntoIterator,
I::Item: Display, // <- no way to say this inline
Vec<T>: Clone, // <- nor this
I::Item is an associated type: an output of the IntoIterator impl, not a
parameter you declared. There is nowhere in <I> to hang : Display off it.
Once you know that, a whole family of “I cannot express this” moments
disappears.
Your task
pub fn summarise<T>(items: Vec<T>) -> String
where
T: Display,
pub fn summarise_any<I>(items: I) -> String
where
I: IntoIterator,
I::Item: Display,
pub fn run(nums: Vec<i64>, words: Vec<String>) -> Vec<String>
Both summarisers render the same shape: the count, then the items joined with
", ". For [1, 2, 3] that is "3 items: 1, 2, 3". An empty input gives
"0 items: " — note the trailing space; the format string is uniform and
nothing special-cases empty.
run returns [summarise(nums), summarise_any(words)].
Two gates you must pass through
1. Clippy will not let you write the bound twice. The starter’s first
function has <T: Display> and where T: Display, and the build fails:
error: bound is defined in more than one place
|
5 | pub fn summarise<T: Display>(items: Vec<T>) -> String
| ^
7 | T: Display,
| ^
That is clippy::multiple_bound_locations, and it is default-on. It bites
learners mid-refactor: you add a second bound in a where clause, forget the
inline one is still there, and the build stops. Pick one location.
2. The second function does not know what it is iterating. I: IntoIterator
says “you can loop over this” and nothing more, so calling .to_string() on an
item fails:
error[E0599]: `<I as IntoIterator>::Item` doesn't implement `Display`
= note: the following trait bounds were not satisfied:
`<I as IntoIterator>::Item: Display`
The fix is one line — but only in the where clause. Try to put it in the
angle brackets and you will not even get a bound error; you will get a parse
failure, because that syntax does not exist.
A note on the nursery
You may have read about clippy::type_repetition_in_bounds and
clippy::trait_duplication_in_bounds. Both are nursery lints: allow by
default, so they will not fire here and you should not count on them. The one
that actually gates you is multiple_bound_locations.
Remember the grade is compile + tests + clippy -D warnings.
Stuck?
Rust reference solution
Sign in to attempt this problem and reveal the reference solution.