我试图使用嵌套迭代器,其中内部迭代器使用外部迭代器中的值。
vec![0;10].iter().flat_map(|&a| {
(0..10).map(|b|{
a + b
})
});
错误:
a
活得不够长(0..10).map(|b|{ ^^^
注意:引用必须对方法调用有效...
如果我移动内部闭包(move |b|{
),这会编译,但我不明白为什么它是必要的,因为a
是一个整数并且可以被复制而不是被移动
答案 0 :(得分:7)
flat_map
和map
都是懒惰的。内部map
不会立即使用a
,但会尝试“保存”它以便以后需要它时借用a
。但由于a
是外部闭包的本地,并且您返回map
的结果,因此借用将变为无效。您需要使用内部迭代器:
vec![0;10].iter().flat_map(|&a| {
(0..10).map(|b|{
a + b
}).collect::<Vec<_>>()
});
当然,这样做效率不高,内部封闭会更好“保持&#34; a
。您可以通过将内部闭包标记为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()
产生的)。