5

I would like to iterate over a vector several times:

let my_vector = vec![1, 2, 3, 4, 5];
let mut out_vector = vec![];
for i in my_vector {
    for j in my_vector {
        out_vector.push(i * j + i + j);
    }
}

The j-loop has a "value used here after move" error. I know that I can place an & before the two my_vectors and borrow the vectors, but it is nice to have more than one way to do things. I would like a little insight as well.

Alternatively, I can write the following:

let i_vec = vec![1, 2, 3, 4, 5, 6];
let iterator = i_vec.iter();
let mut out_vec = vec![];
for i in iterator.clone() {
    for j in iterator.clone() {
        out_vec.push(i * j + i + j);
    }
}

I looked at What's the most efficient way to reuse an iterator in Rust?:

Iterators in general are Clone-able if all their "pieces" are Clone-able.

Is the actual heap allocated data a "piece" of the iterator or is it the memory address that points to the heap data the aforementioned piece?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Dragon
  • 61
  • 1
  • 7

1 Answers1

7

Cloning a slice iterator (this is the type of iterator you get when calling iter() on a Vec or an array) does not copy the underlying data. Both iterators still point to data stored in the original vector, so the clone operation is cheap.

The same is likely true for clonable iterators on other types.

In your case, instead of calling i_vec.iter() and then cloning it, you can also call i_vec.iter() multiple times:

for i in i_vec.iter() {
    for j in i_vec.iter() {

which gives the same result but is probably more readable.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
interjay
  • 107,303
  • 21
  • 270
  • 254
  • I guess that using i_vec.iter() twice does not suffer the wrath of the borrow checker, since we are not binding i_vec to something. – Dragon Jul 19 '17 at 16:23
  • 1
    @Dragon It works because it takes a read-only reference each time and it's fine to have more than one. The problem with your original code is that `for i in my_vector` consumes the vector (it's used to move data out of the vector) so you can't use the vector after that. – interjay Jul 19 '17 at 16:28
  • 1
    Even more idiomatic (as Clippy tells you) is `for i in &i_vec { for j in &i_vec { ... }}`. – Shepmaster Jul 19 '17 at 17:08
  • @Shepmaster: That's true, but the question already mentioned that method so I didn't mention it in my answer. – interjay Jul 19 '17 at 20:39