Reputation: 5895
Here is my code:
fn find_rects<'a >(
rects: & Vec<&'a Rectangle>, // reference of a vec containing Rectangle references
width_limit: u32)
-> Vec<&'a Rectangle> // returns a vec of Rectangle references
{
rects
.iter()
.filter(|x| x.width > width_limit)
.collect()
}
It failed to compile. The error message says:
.collect()
^^^^^^^ value of type `Vec<&Rectangle>` cannot be built from `std::iter::Iterator<Item=&&Rectangle>`
And I found an answer to use .copied().collect()
instead of .collect()
. I tested and it works.
But I don't know the reason.
Upvotes: 1
Views: 632
Reputation: 13879
If my_vec: Vec<T>
, then my_vec.iter()
is an iterator over &T
. But in this case T
is &Rectangle
so the iterator is over &&Rectangle
, which is a distinct type from &Rectangle
and so cannot be collect
ed into a Vec<&Rectangle>
.
iterator.copied()
takes an iterator over &U
and produces an iterator over U
by copying (in the sense of Copy
) each element (by dereferencing it; copied()
is equivalent to iterator.map(|&x| x)
and iterator.map(|x| *x)
).
All that's left is to recognize that U
is &Rectangle
and that &U: Copy
for any U
, including when U
is &Rectangle
. So Iterator<Item=&&Rectangle>::copied()
produces an iterator of &Rectangle
, which can indeed be collect
ed into a Vec<&Rectangle>
(or, really, any FromIterator
, of which Vec
is just one).
Upvotes: 5