Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

クロージャ

クロージャは、周囲の環境をキャプチャできる関数です。たとえば、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());

}