Is there a better way to push to a Vec while iterating over it?

⚓ Rust    📅 2026-07-09    👤 surdeus    👁️ 2      

surdeus

I would like write a function which iterates over the elements of a Vec, processes each element with some function, and sometimes pushes a new element to the back of the Vec depending on the outcome of this processing. Something along the lines of this:

// Process a single element from the queue and determine if a new element needs
// to be enqueued
fn process_element(input: u8) -> bool { todo!() }

// Process a sequence of elements until it is exhausted, adding a new element to
// the back of the sequence on each iteration if so dictated by the processing
// algorithm
fn process_list(mut v: Vec<u8>) {
    for &elem in &v {
        if process_element(elem) { v.push(42) }
    }
}

Playground

Importantly, process_list should iterate over all elements of v, including the new ones that were pushed to the back during processing of earlier elements.

This does not compile though:

error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
  --> src/lib.rs:12:36
   |
11 |     for &elem in &v {
   |                  --
   |                  |
   |                  immutable borrow occurs here
   |                  immutable borrow later used here
12 |         if process_element(elem) { v.push(42) }
   |                                    ^^^^^^^^^^ mutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.

It seems that in order to create the iterator which powers thisfor loop, v must be either moved or borrowed, both of which disallow the mutable borrow needed by Vec::push within the loop.

I believe the implementation problem can be solved by switching to a while loop like this:

fn process_list(mut v: Vec<u8>) {
    let mut i = 0;
    while let Some(&elem) = v.get(i) {
        if process_element(elem) { v.push(42) }
        i += 1;
    }
}

Playground

But this requires manual management of an iteration index (i) and just doesn't feel as clean or idiomatic as using iterators. Is there a way to implement this behavior using iterators?

4 posts - 3 participants

Read full topic

🏷️ Rust_feed