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
}));
}
The code referenced as "1", if uncommented, compiles and runs just fine, but the code referenced as "2" does not compile, failing with the message:
error[E0596]: cannot borrow `v2` as mutable, as it is a captured variable in a `Fn` closure
How can I fix this, if I want keep the code structure as it is?
In my real code, I want connect two traits. One of them will call a callback on event, and the other has a function to handle the callback:
trait Foo {
fn add_callback(&mut self, cb: Box<Fn(i32)>);
}
trait Boo {
fn on_new_data(&mut self, data: i32);
}
I want to create a trait object with Boo
, wrap it with Rc
, and pass it to Foo::add_callback
in the form of |x:i32| Rc::get_mut(&mut boo).unwrap().on_new_data(x)
The entire error message is mostly helpful:
error[E0596]: cannot borrow `v2` as mutable, as it is a captured variable in a `Fn` closure
--> src/main.rs:17:19
|
17 | *Rc::get_mut(&mut v2).unwrap() = tmp + 1;
| ^^^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
--> src/main.rs:15:17
|
15 | f1(Box::new(move |x: i32| {
| _________________^
16 | | let tmp = *v2;
17 | | *Rc::get_mut(&mut v2).unwrap() = tmp + 1;
18 | | x + *v2
19 | | }));
| |_____^
Changing f1
to accept a FnMut
and making the variable mutable allows the code to compile:
fn f1(mut cb: Box<FnMut(i32) -> i32>) {
This is needed in order to mutate the captured variable v2
, required by the &mut v2
argument to Rc::get_mut
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With