Reused vec in loop

fn test() {
    let mut vec = vec![];
    for i in 0..1000000000 {
        let s = format!("hello world {}", i);
        vec.push(s.as_str());
        vec.iter().for_each(|s| println!("do something: {}", s));
        vec.clear();
    }
}

In a situation like this, Vec runs into a lifetime issue, showing the error s does not live long enough. However, by looking at the code we can tell that s will be removed from the Vec after the loop ends, so there is actually no problem. In such scenarios, how can we reuse the Vec and resolve the lifetime issue—either in a safe or unsafe way?

add this line after vec.clear():

    vec.clear();
+   vec = vec.into_iter().map(|_| unreachable!()).collect();

UPDATE:

since this was selected as the answer, you can read previous threads on the same topic for detailed explanation, such as:

8 Likes

The wild linker authors explained a trick to solve this exact problem a couple weeks ago. Wild Performance Tricks | David Lattimore
In the section "Buffer reuse".

3 Likes

A one-liner to replace vec.clear():

vec = vec.into_iter().filter_map(|_| None).collect();
3 Likes

For extra context, we may focus on explaining the root cause of the issue and why the new code fixes it. Adding the reasoning not only helps prevent the same or similar mistakes in the future, but also makes the answer more valuable for the original poster and others who might read it later and he does not know it yet. In other words, Q&A like this can be a great learning resource

In Rust, every .into() means it moves/consumes the value. If you use .iter(), it borrows/references the value, while .into_iter() moves/consumes it

Additionally, any .as_() method is also borrowing/referencing the value, such as .as_str()

CMIIW :>

1 Like

Really appreciate you taking the time to write this up.

In the future it should be more convenient: Tracking Issue for `Vec::recycle` · Issue #148227 · rust-lang/rust · GitHub

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.