0

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.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Zach
  • 5,715
  • 12
  • 47
  • 62
  • 1
    [Copied ref](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.copied) _This is useful when you have an iterator over `&T`, but you need an iterator over `T`._ This is the case that your error points. – Ömer Erden Oct 12 '22 at 04:59
  • `.iter()` makes an iterator over `&T` from a `&Vec`, so you end up with `&&Rectangle`s. `.copied()` derefs and copies each element to give you `&Rectangle`s again. – FZs Oct 12 '22 at 05:09
  • (Off-topic): [you should take `&[&'a Rectangle]` as argument](https://stackoverflow.com/q/40006219/8376184) – FZs Oct 12 '22 at 05:11

1 Answers1

3

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 collected 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 collected into a Vec<&Rectangle> (or, really, any FromIterator, of which Vec is just one).

BallpointBen
  • 9,406
  • 1
  • 32
  • 62