让我们手动对闭包进行脱糖。
struct Closure1 {
client: BasicClient,
}
impl FnOnce<()> for Closure1 {
type Output = BasicClient;
extern "rust-call" fn call_once(self, (): ()) -> BasicClient {
<Self as Fn<()>>::call(&self, ())
}
}
impl FnMut<()> for Closure1 {
extern "rust-call" fn call_mut(&mut self, (): ()) -> BasicClient {
<Self as Fn<()>>::call(&*self, ())
}
}
impl Fn<()> for Closure1 {
extern "rust-call" fn call(&self, (): ()) -> BasicClient {
<BasicClient as Clone>::clone(&self.client)
}
}
struct Closure2 {
client: BasicClient,
}
impl FnOnce<()> for Closure2 {
type Output = BasicClient;
extern "rust-call" fn call_once(self, (): ()) -> BasicClient {
self.client
}
}
fn with_client(
client: BasicClient,
) -> impl Filter<Extract = (BasicClient,), Error = Infallible> + Clone {
warp::any().map(Closure1 { client })
}
fn with_client(
client: BasicClient,
) -> impl Filter<Extract = (BasicClient,), Error = Infallible> + Clone {
let clone = <BaseClient as Clone>::clone(&clone);
warp::any().map(Closure1 { client: clone })
}
如你所见,问题不在于我们移动client进入关闭。问题是我们移动它在......之外关闭。当您搬出某物时,您必须拥有数据的所有权:因此,FnOnce。您使用克隆创建闭包的事实并不重要。但是当你克隆封闭内,您只使用共享引用-因此您不需要所有权,甚至不需要独占访问-因此Fn。