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:
a
does 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