これはありません。クロージャの仕組みに間違った精神モデルがあるかもしれません。
クロージャは、定義する環境から値を取得する余分な初期引数を持つ関数の単なる構文的なショートハンドです。
fn factory() -> Box<Closure> {
let num = 5;
Box::new(Closure { num: num })
}
struct Closure {
num: i32,
}
impl Closure {
pub fn invoke(&self, x: i32) -> i32 {
x + self.num
}
}
fn main() {
let f = factory();
let answer = f.invoke(1);
assert_eq!(6, answer);
}
注num
が「閉鎖」が構築された時点で、「閉鎖」にを撮影し取得する方法:我々は論理的同等である何かにあなたの例を書き換えることができます。クロージャの本体はself
(これは本当のクロージャーのために魔法にかけられています)経由でこれにアクセスします。 Closure
タイプが存在するが、匿名ある
:このし、元のコードの間
唯一の違いはということです。つまり、型の名前を直接指定することはできません。戻り型にFn(i32) -> i32
を使用する必要があります。
上記のため、ボックス化された特性オブジェクトではなく、ボックス化されたコンクリートタイプが返されます。どのように "クロージャー"が使われているかという点では、これは私たちにはあまり重要ではありません。 Box<Fn(i32) -> i32>
を返すことができない理由は...
Fn
を実装していません。これはまだ安定したコードではできません。 がの場合、invoke
とほとんど同じです。
factory
機能の外で「クロージャー」の本体を定義します。しかし、これは単なる構文上の違いです:クロージャーの本体は、の本体がの実行の「一部」であるinvoke
の本体よりも、この「 factory
」の実行の「一部」ではありません。
だから、うまくいけば、あなたはその実行がfactory
機能へないリターンん見ることができます:それはちょうど便宜上factory
内を定義するために起こるさまざまな機能になります。
これは非常に便利です!ありがとう。 – enaJ