I've been having some issues with moving reference counted variables into closures which need to implement FnMut.
The following code works fine:
use std::rc::Rc;
fn main() {
let callback;
let data: Rc<Vec<f32>> = Rc::new(Vec::new());
{
let data = data.clone();
callback = move || {
data.iter().for_each(|v| println!("{}", v));
};
consumer(callback);
}
}
fn consumer<D>(callback: D)
where
D: FnMut(),
{
}
If I change the closure to:
callback = move || {
data;
};
The compiler produces the error:
--> src/test1.rs:11:20
|
11 | callback = move || {
| ^^^^^^^ this closure implements `FnOnce`, not `FnMut`
12 | data;
| ---- closure is `FnOnce` because it moves the variable `data` out of its environment
...
15 | consumer(callback);
| -------- the requirement to implement `FnMut` derives from here
This example works:
callback = move || {
let x = data[0];
println!("{}", x);
};
This example does not:
callback = move || {
let x = data;
println!("{}", x[0]);
};
With let data: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new()));, this works:
callback = move || {
let x = data.lock().unwrap();
};
This does not:
callback = move || {
let x = data;
};
What is the reasoning behind this?