2016-08-17 10 views
2
use std::rc::Rc; 

fn f1(cb: Box<Fn(i32)->i32>) { 
    let res = cb(15); 
    println!("res {}", res); 
} 

fn main() { 
    let mut v2 = Rc::new(5_i32); 
    //1 
    //f1(Box::new(move |x: i32| *v2 + x)); 
    //2 
    f1(Box::new(move |x: i32| { let tmp = *v2; *Rc::get_mut(&mut v2).unwrap() = tmp + 1; x + *v2 })); 
} 

コンパイルされていないとコンパイルされて正常に実行される場合、 "1"Rcでクロージャを使用するときにFnクロージャでキャプチャされた外部変数を借りることはできません

しかし、であるように、コードはコンパイルされません、メッセージ

で失敗することは、私がしたい場合、私は、この問題を解決するにはどうすればよいのFn閉鎖のように変更可能

をキャプチャし、外側の変数を借りることができませんそのままのコード構造を保つ?

実際のコードでは、2つの接続が必要ですtrait s。そのうちの一つは、イベントにコールバックを呼び出しますし、他のコールバックを処理する機能を持っています

trait Foo { 
    pub fn add_callback(&mut self, cb: Box<Fn(i32)>); 
} 

trait Boo { 
    pub fn on_new_data(&mut self, data: i32); 
} 

私はの形で、Booで形質オブジェクトを作成Rcでそれをラップし、Foo::add_callbackにそれを渡したいです|x:i32| Rc::get_mut(&mut boo).unwrap().on_new_data(x)

答えて

2

エラーメッセージは、ほとんど有用である:

error: cannot borrow captured outer variable in an `Fn` closure as mutable 
    --> src/main.rs:13:27 
13 |>   *Rc::get_mut(&mut v2).unwrap() = tmp + 1; 
    |>       ^^ 
help: consider changing this closure to take self by mutable reference 
    --> src/main.rs:11:17 
11 |>  f1(Box::new(move |x: i32| { 
    |>    ^

Fn閉鎖に

FnMutを受け入れるf1を変更し、可変可変を行うよう可変捕獲外側の変数を借りることができないコードをコンパイルすることを可能にする:

fn f1(mut cb: Box<FnMut(i32) -> i32>) { 

これは必要とされていますキャプチャされた変数v2&mut v2引数で必要とされる)をRc::get_mutに変更します。

関連する問題