直到此刻,我认为move |...| {...}
会将变量移动到闭包内部,并且闭包只会实现FnOnce
,因为你只能移动变量一次。但令我惊讶的是,我发现以下代码也能工作:
extern crate futures;
use futures::stream;
use futures::stream::{Stream, StreamExt};
use std::rc::Rc;
#[derive(Debug)]
struct Foo(i32);
fn bar(r: Rc<Foo>) -> Box<Stream<Item = (), Error = ()> + 'static> {
Box::new(stream::repeat::<_, ()>(()).map(move |_| {
println!("{:?}", r);
}))
}
fn main() {
let r = Rc::new(Foo(0));
let _ = bar(r);
}
尽管 "map" 函数具有以下签名:
fn map<U, F>(self, f: F) -> Map<Self, F>
where
F: FnMut(Self::Item) -> U,
对我来说,使用 move
关键字创建的 FnMut
闭包甚至具有 'static
生命周期,这让我感到惊讶。我在哪里可以找到关于 move
的详细信息?或者它实际上是如何工作的?
move
会导致变量在闭包创建时被“移动”到闭包内部,这不会阻止闭包被调用多次。如果闭包代码从捕获的变量中移出任何值,即使用这些值,闭包将变为FnOnce
类型。只有当变量首先被移入闭包时,你才能将其值移出捕获的变量,但仅仅将值移入闭包本身并不会使闭包成为FnOnce
类型。 - Sven Marnach