Rust by Example

8.2.5 クロージャを返す関数

クロージャを引数として使用することができるのと同様、返り値をクロージャにすることもできます。ただし、現在の仕様ではRustは返り値をジェネリック型にすることはできません。無名クロージャは、定義上型が不明なので、返り値として渡すには、具体的な(concrete)型にする必要があります。これはbox化することで可能です。

返り値となるクロージャが持つトレイトには若干の制限があります。

  • Fn: 通常どおりです。
  • FnMut: 通常どおりです。
  • FnOnce: ほぼ同じ機能を持つFnBoxが必要になります。この仕様は将来的には廃止される可能性があります。

さらに、リファレンスではなく値による捕捉が起きることを保証するため、moveキーワードを使用する必要があります。リファレンスでの捕捉の場合、関数の実行が終わった段階で、リファレンスを開放する必要があるため、クロージャの中に不当なリファレンスが残ってしまうためです。

fn create_fn() -> Box<Fn()> { let text = "Fn".to_owned(); Box::new(move || println!("This is a: {}", text)) } fn create_fnmut() -> Box<FnMut()> { let text = "FnMut".to_owned(); Box::new(move || println!("This is a: {}", text)) } fn main() { let fn_plain = create_fn(); let mut fn_mut = create_fnmut(); fn_plain(); fn_mut(); }

See also:

BOX化, Fn, FnMut, and ジェネリクス.