`move` moving too much

Consider the three approaches here to calculate the vector new

fn main() {
    let v = vec![false; 100];
    
    // let new1 = (0..10).map(|i|
    //     (0..10).map(|j| v[i*10 + j])
    // ).flatten().collect::<Vec<_>>();
    
    // let new2 = (0..10).map(|i|
    //     (0..10).map(move |j| v[i*10 + j])
    // ).flatten().collect::<Vec<_>>();
    
    let new3 = {
        let mut new3 = vec![false; 100];
        for i in 0..10{
            for j in 0..10{
                new3[i*10 + j] = v[i*10 + j];
            }
        }
    };
    
}

The first one does not work because the closure in the second line may outlive i and the denotation of i cannot be found if this happens. The second one does not work because the move keyword tries to move in v. How can I move i but not v?

I do not want to use for loops like in the third example. I want to use a style similar to the first or the second one.

You can create a reference to v and move that into the closure. It's a little silly but it gets the job done.

Playground

fn main() {
    let v = vec![false; 100];
    
    let new1 = (0..10).map(|i| {
        let v = &v;
        (0..10).map(move |j| v[i*10 + j])
    }).flatten().collect::<Vec<_>>();
}
6 Likes

Why doesn't this version work?

fn main() {
    let v = vec![false; 100];
    
    let new1 = (0..10).map(|i| {
        //let v = &v;
        (0..10).map(move |j| &v[i*10 + j])
    }).flatten().collect::<Vec<_>>();
}

v is still being moved into the closure, you're taking a reference to v's new location inside the closure.

3 Likes