为什么嵌套迭代器闭包不会从外部范围复制值
Why nested iterator closures won't copy values from outer scope
我正在尝试使用嵌套迭代器,其中内部迭代器使用外部迭代器的值。
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...
如果我移动内部闭包 (move |b|{
),这会编译,但我不明白为什么有必要,因为 a
是一个整数并且可以被复制而不是被移动.
flat_map
和map
都是懒惰的。内部 map
不会立即使用 a
而是试图“保存”它以备后用,因此借用了 a
。但是由于 a
是外部闭包的局部变量,而你 return map
的结果,借用将变得无效。您需要使用内部迭代器:
vec![0;10].iter().flat_map(|&a| {
(0..10).map(|b|{
a + b
}).collect::<Vec<_>>()
});
当然这样效率不高,内部闭包"keep"a
会好很多。您可以通过将内部闭包标记为 move
:
来做到这一点
vec![0;10].iter().flat_map(|&a| {
(0..10).map(move |b|{
a + b
})
});
通常情况下,编译器不会让您这样做,因为 flat_map
闭包不拥有 a
,它仅具有对它的引用。然而,
由于 Rust 中的数字类型(如 isize
)实现了 Copy
特性,编译器将复制 a
而不是尝试移动它,从而提供您想要的行为。请注意,这也是允许在 flat_map
中取消引用 a
(使用 |&a|
)的原因;通常这需要拥有 a
,而不仅仅是对它的引用(这是 .iter()
的结果)。
我正在尝试使用嵌套迭代器,其中内部迭代器使用外部迭代器的值。
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...
如果我移动内部闭包 (move |b|{
),这会编译,但我不明白为什么有必要,因为 a
是一个整数并且可以被复制而不是被移动.
flat_map
和map
都是懒惰的。内部 map
不会立即使用 a
而是试图“保存”它以备后用,因此借用了 a
。但是由于 a
是外部闭包的局部变量,而你 return map
的结果,借用将变得无效。您需要使用内部迭代器:
vec![0;10].iter().flat_map(|&a| {
(0..10).map(|b|{
a + b
}).collect::<Vec<_>>()
});
当然这样效率不高,内部闭包"keep"a
会好很多。您可以通过将内部闭包标记为 move
:
vec![0;10].iter().flat_map(|&a| {
(0..10).map(move |b|{
a + b
})
});
通常情况下,编译器不会让您这样做,因为 flat_map
闭包不拥有 a
,它仅具有对它的引用。然而,
由于 Rust 中的数字类型(如 isize
)实现了 Copy
特性,编译器将复制 a
而不是尝试移动它,从而提供您想要的行为。请注意,这也是允许在 flat_map
中取消引用 a
(使用 |&a|
)的原因;通常这需要拥有 a
,而不仅仅是对它的引用(这是 .iter()
的结果)。