5

Suppose we have a vector of some type that can be cloned

let foo_vec = vec![clonable_item_1, clonable_item_2, ...];

How to determine whether to use .clone() and .cloned() when iterating?

foo_vec.iter().cloned()...

// vs

foo_vec.clone().iter()...

I couldn't find anything written about the difference between the two. What's the difference?

mildog8
  • 2,030
  • 2
  • 22
  • 36
  • 1
    As per the linked answer, `foo_vec.iter().cloned()` is like doing `foo_vec.iter().map(|x| x.clone())`, which is indeed different from first cloning the vector and iterating on that copy. See also: https://stackoverflow.com/questions/34733811/what-is-the-difference-between-iter-and-into-iter – E_net4 Feb 23 '22 at 11:07
  • 2
    `foo_vec.clone().iter()` should be avoided if possible since it clones the entire vector up front, using up a lot of memory, whereas `foo_vec.iter().cloned()` only clones the items one at a time. – Jmb Feb 23 '22 at 11:20

1 Answers1

10

They're not at all equal. If anything, it should be v.iter().cloned() vs. v.clone().into_iter(), both produce an iterator over owned T while v.clone().iter() produces an iterator over &T.

v.clone().into_iter() clones the Vec, allocating a Vec with the same size and cloning all elements into it, then converts this newly created Vec into an iterator. v.iter().cloned(), OTOH, creates a borrowed iterator over the Vec that yields &T, then applies the cloned() iterator adapter to it, which on-the-fly clones the &T produced by Iterator::next() to produce an owned T. Thus it doesn't need to allocate a new vector.

Because of that, you should always prefer v.iter().cloned() when possible (usually it is, but Vec's IntoIter has additional capabilities, like getting the underlying slice that may be required).

Masklinn
  • 34,759
  • 3
  • 38
  • 57
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77