Rust 中文社区 · 更新于 2017-09-24 22:00:29

闭包的实现

Rust 的闭包实现与其它语言有些许不同。它们实际上是trait的语法糖。在这以前你会希望阅读trait章节,和trait对象

都理解吗?很好。

理解闭包底层是如何工作的关键有点奇怪:使用()调用函数,像foo(),是一个可重载的运算符。到此,其它的一切都会明了。在Rust中,我们使用trait系统来重载运算符。调用函数也不例外。我们有三个trait来分别重载:

# mod foo {
pub trait Fn<Args> : FnMut<Args> {
    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

pub trait FnMut<Args> : FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

pub trait FnOnce<Args> {
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
# }

你会注意到这些 trait 之间的些许区别,不过一个大的区别是selfFn获取&selfFnMut获取&mut self,而FnOnce获取self。这包含了所有3种通过通常函数调用语法的self。不过我们将它们分在 3 个 trait 里,而不是单独的 1 个。这给了我们大量的对于我们可以使用哪种闭包的控制。

闭包的|| {}语法是上面 3 个 trait 的语法糖。Rust 将会为了环境创建一个结构体,impl合适的 trait,并使用它。

这部分引用自The Rust Programming Language中文版