閉包的實現
Rust 的閉包實現與其它語言有些許不同。它們實際上是trait的語法糖。在這以前你會希望閱讀trait章節,和trait對象。
都理解嗎?很好。
理解閉包底層是如何工作的關鍵有點奇怪:使用()調用函數,像foo(),是一個可重載的運算符。到此,其它的一切都會明瞭。在Rust中,我們使用trait系統來重載運算符。調用函數也不例外。我們有三個trait來分別重載:
#![allow(unused)] fn main() { 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 之間的些許區別,不過一個大的區別是self:Fn獲取&self,FnMut獲取&mut self,而FnOnce獲取self。這包含了所有3種通過通常函數調用語法的self。不過我們將它們分在 3 個 trait 裡,而不是單獨的 1 個。這給了我們大量的對於我們可以使用哪種閉包的控制。
閉包的|| {}語法是上面 3 個 trait 的語法糖。Rust 將會為了環境創建一個結構體,impl合適的 trait,並使用它。
這部分引用自The Rust Programming Language中文版