rustvectorcloneborrow

How to push a variable's value into a vector but keep the variable alive?


I got a question about how to move a variable into a vector but without destroying this variable because it has to be reused in a loop. Below shows what I mean:

type Letter = char;
type LetterSet = Vec<Letter>;

fn main() {
    let mut v = Vec::<LetterSet>::new();
    let mut letterset: LetterSet = LetterSet::new(); 

    for i in 0..5 {
        let a = (48 + i as u8) as char;
        letterset.push(a);
        if i % 2 == 1 {
            let b = (65 + i as u8) as char;
            letterset.push(b); 
        } else {
            let c = (97 + i as u8) as char;
            letterset.push(c);
        }
        v.push(letterset.clone());
        letterset.clear();
    }

    for letterset in v {
        for letter in letterset {
            print!("{} ", letter);
        }
        println!("");
    } 
}

The code above runs. However, I want to avoid clone in

        v.push(letterset.clone());
        letterset.clear();

since letterset will be cleared anyways. Rather, I want to move its contents into v but keep it alive, because letterset has to be for the next iteration.

I tried to remove .clone() but obviously this results in a 'borrow after move' error. I wonder how to do it, thanks.


Solution

  • Why not create a new LetterSet at every iteration? Moving a Vec is only moving references to the heap, it's pretty cheap.

    If you really want to re-use the same var you can use std::mem::take which will return the Vec and replace the original variable by its default (an empty vec) - this has the same behaviour since you're making a new Vec every time.

    v.push(std::mem::take(&mut letterset));
    

    You can also skip .clear() since it'll be already empty.