型匿名性
クロージャで簡潔にスコープから変数をキャプチャできます。なにか注意する点は あるのでしょうか? もちろんです。クロージャを引数として取る時、ジェネリック を使わなくてはいけません。
#![allow(unused_variables)] fn main() { // `F`はジェネリックである必要がある。 fn apply<F>(f: F) where F: FnOnce() { f(); } }
クロージャが作られた時、コンパイラはキャプチャした変数を保存する匿名の
、Fn、FnMut、FnOnceの3つのトレイトの内一つをその型に対して実装した
構造体を作成し、呼び出されるまで待ちます。
この構造体は型が未指定なため、関数での使用にはジェネリックが必要です。
しかし、型パラメータ<T>を指定するだけではまだ曖昧です。そのため、Fn、
FnMut、FnOnceのどれを実装しているか明示する必要があります。
// `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); }