Is there a better way to push to a Vec while iterating over it?
⚓ Rust 📅 2026-07-09 👤 surdeus 👁️ 2I 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) }
}
}
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;
}
}
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
🏷️ Rust_feed