クロージャ
クロージャは、周囲の環境をキャプチャできる関数です。たとえば、x 変数をキャプチャするクロージャは次のようになります。
|val| val + x
クロージャの構文と機能は、その場で使用するのに非常に便利です。クロージャの呼び出しは、関数の呼び出しとまったく同じです。ただし、入力型と戻り値の型はどちらも推論_できます_が、入力変数名は指定_しなければなりません_。
クロージャのその他の特徴は次のとおりです。
- 入力変数を囲むのに
()の代わりに||を使用する。 - 1行の式では本体を区切る記号(
{})が任意である(それ以外の場合は必須)。 - 外側の環境変数をキャプチャできる。
fn main() { let outer_var = 42; // 通常の関数は、周囲の環境にある変数を参照できない //fn function(i: i32) -> i32 { i + outer_var } // TODO: 上の行のコメントを外して、コンパイラエラーを確認してください。コンパイラは // 代わりにクロージャを定義することを提案します。 // クロージャは無名であり、ここでは参照に束縛しています。 // アノテーションは関数のアノテーションと同じですが、省略可能です。 // 本体を囲む `{}` も同様に省略可能です。これらの名前のない関数は、 // 適切に名前付けされた変数に代入されます。 let closure_annotated = |i: i32| -> i32 { i + outer_var }; let closure_inferred = |i | i + outer_var ; // クロージャを呼び出す。 println!("closure_annotated: {}", closure_annotated(1)); println!("closure_inferred: {}", closure_inferred(1)); // クロージャの型が一度推論されると、別の型で再度推論することはできない。 //println!("別の型で closure_inferred を再利用することはできません: {}", closure_inferred(42i64)); // TODO: 上の行のコメントを外して、コンパイラエラーを確認してください。 // 引数を取らず、`i32` を返すクロージャ。 // 戻り値の型は推論される。 let one = || 1; println!("1を返すクロージャ: {}", one()); }