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
andmap
are lazy. The innermap
does not usea
immediately but tries to “save” it for when it will be needed later thus borrowsa
. But sincea
is local to the outer closure and you returnmap
's result, that borrow would become invalid. You would need to consume the inner iterator: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 asmove
:Normally, the compiler would not let you do this, because the
flat_map
closure does not owna
, it merely has a reference to it. However, since the numeric types in Rust (likeisize
) implement theCopy
trait, the compiler will copya
instead of trying to move it, giving the behavior you want. Note that this is also the reason why you are allowed to dereferencea
(using|&a|
) in theflat_map
; normally that would have required owninga
, not merely a reference to it (which is what.iter()
yields).