クロージャーを関数の戻り値にする(@rust)

クロージャーを関数の戻り値にするときにも、Fn/FnMut/FnOnce指定が必要です。なぜならクロージャーの受け取りと同じくクロージャーの型は不明なので、

さらに関数の戻り値とするためにはクロージャーに渡される変数をmoveで参照では無く値渡しにしないといけません。以下の例でdataはクロージャーに渡しても戻り値では無い(参照が無効になることはない)ので、ここでのmoveはあっても無くても、値渡しだと時間が余計にかかるだけで、結果は同じですが、create_fn()中のクロージャーにはmoveがないとtextが参照では関数の戻りで参照無効となるのでコンパイルが通りません。

// return a closure
fn create_fn() -> impl Fn() {
    let text = "Fn".to_owned();
    move || println!("This is a: {}", text)
}

fn main() {
    // return a closure
    let data = vec![1, 2, 3];

    // you don't need 'move' in this case becuase data is still available after this line
    let closure = move || println!("captured {data:?} by value");   
    closure();

    // call function and receive closure
    let fn_plain = create_fn(); // return a closure
    
    fn_plain();

 

admin

 

カテゴリーRust