为什么嵌套的迭代器闭包不会从外部作用域复制值 [英] Why nested iterator closures won't copy values from outer scope
问题描述
我正在尝试使用嵌套迭代器,其中内部迭代器使用外部迭代器的值。
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
})
});
错误:
a
寿命不足
(0..10).map(|b|{
^^^
注意:引用必须对方法调用有效...
note: reference must be valid for the method call...
如果我移动内部闭包( move | b | {
),这会编译,但是我不会理解 a
是整数并且可以被复制而不是移动的原因。
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.
推荐答案
flat_map
和 map
都很懒,内部的 map
不会立即使用 a
,而是尝试在以后需要时保存,因此借用了 a
,但是由于 a
是外部闭包的局部变量,因此您返回 map
的结果,您将需要使用内部迭代器:
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<_>>()
});
当然这不是有效的方法,内部闭包保持会更好。 code> a 。您可以通过将内部闭合标记为 move
来做到这一点:
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
})
});
通常,编译器不允许您这样做,因为 flat_map
闭包不拥有 a
,它仅具有对它的引用。但是,
由于Rust中的数字类型(如 isize
)实现了 Copy
特性,因此编译器将复制 a
而不是尝试移动它,以提供所需的行为。请注意,这也是允许您取消引用 a
(使用 |& a |
)的原因。 flat_map
;通常,这需要拥有 a
,而不仅仅是拥有它(这是 .iter()
的收益)
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).
这篇关于为什么嵌套的迭代器闭包不会从外部作用域复制值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!