型匿名性

クロージャで簡潔にスコープから変数をキャプチャできます。なにか注意する点は あるのでしょうか? もちろんです。クロージャを引数として取る時、ジェネリック を使わなくてはいけません。


#![allow(unused_variables)]
fn main() {
// `F`はジェネリックである必要がある。
fn apply<F>(f: F) where
    F: FnOnce() {
    f();
}
}

クロージャが作られた時、コンパイラはキャプチャした変数を保存する匿名の 、FnFnMutFnOnceの3つのトレイトの内一つをその型に対して実装した 構造体を作成し、呼び出されるまで待ちます。

この構造体は型が未指定なため、関数での使用にはジェネリックが必要です。 しかし、型パラメータ<T>を指定するだけではまだ曖昧です。そのため、FnFnMutFnOnceのどれを実装しているか明示する必要があります。

// `F`は`Fn`を実装している必要があり、クロージャは何もとらず何も返さない。
// `print`にはこれが正しい。
fn apply<F>(f: F) where
    F: Fn() {
    f();
}

fn main() {
    let x = 7;

    // `x`を匿名の型としてキャプチャし、それに
    // `Fn`を実装する。これを`print`に格納する。
    let print = || println!("{}", x);

    apply(print);
}

こちらも参照: