'How to iterate over a vector without moving it

I have a recursive type which doesn't implement copy

struct Node {
    board: Board,
    children: Option<Vec<Node>>,
}

I have a Vector of these nodes, I want to call a method on each, and then pass them on to another function.

fn foo() {
    let mut nodes: Vec<Node> = get_nodes();
    for i in 0..nodes.len() {
        nodes[i].grow();
    }
    pick_node(nodes);
}

This works, but frustratingly

fn foo() {
    let nodes: Vec<Node> = get_nodes();
    for mut node in nodes {
        node.grow();
    }
    pick_node(nodes);
}

causes an error because "nodes moved due to this implicit call to .into_iter()"

Is there a version of for _ in _ that just gets me references to each member of the vector in turn, without moving or copying, like I get when I use a range like in the first version? It's an issue that comes up a lot for me, and it's been hard to find an answer for some reason. Like Clippy says, the iterator is probably faster, and clearer, and just seems idiomatic.



Solution 1:[1]

I believe the methods you're looking for are iter and/or iter_mut. So your code will look like the following:

for node in nodes.iter_mut() {
    node.grow();
}

Alternatively, &Vec<T> and &mut Vec<T> both have IntoIterator implementations which return the iterator provided by iter or iter_mut respectively. So the following is also equivalent to the above:

for node in &mut nodes {
    node.grow();
}

Edit

All of the above is correct, just to add a little more clarification:

for pattern in iterable {
    /* body */
}

essentially just desugars to the following:

let mut iter = IntoIterator::into_iter(iterable);
loop {
    match iter.next() {
        Some(pattern) => { /* body */ },
        None => break,
    }
}

into_iter requires an owned self, so that's why your vector is moved when it's substituted in the place of iterable. Ownership of the vector is transferred to its into_iter function. On the other hand, when you put &vec or &mut vec in the place of iterable, it's the references which are copied/moved, leaving the original vector in place.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1