I'm trying to use nested iterators, where the inner iterator uses value from the outer iterator.
vec![0;10].iter().flat_map(|&a| {
    (0..10).map(|b|{
        a + b
    })
});
error:
adoes not live long enough(0..10).map(|b|{ ^^^note: reference must be valid for the method call...
This compiles if I move the inner closure (move |b|{), but I don't understand why it is necessary, given that a is an integer and could have been copied instead of moved.
Both flat_map and map are lazy. The inner map does not use a immediately but tries to “save” it for when it will be needed later thus borrows a. But since a is local to the outer closure and you return map's result, that borrow would become invalid. You would need to consume the inner iterator:
vec![0;10].iter().flat_map(|&a| {
    (0..10).map(|b|{
        a + b
    }).collect::<Vec<_>>()
});
Of course that's not efficient, and it would be much better for the inner closure to "keep" a. You would do this by marking the inner closure as move:
vec![0;10].iter().flat_map(|&a| {
    (0..10).map(move |b|{
        a + b
    })
});
Normally, the compiler would not let you do this, because the flat_map closure does not own a, it merely has a reference to it. However,
since the numeric types in Rust (like isize) implement the Copy trait, the compiler will copy a instead of trying to move it, giving the behavior you want. Note that this is also the reason why you are allowed to dereference a (using |&a|) in the flat_map; normally that would have required owning a, not merely a reference to it (which is what .iter() yields).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With