I'm trying to pass in a closure to a function that will then mutate something passed into it within the scope of the function. Based on my current understanding of Rust, that should look something like this:
pub fn call_something(callback: &FnOnce(&mut Vec<i32>)) {
let mut my_vec = vec![0, 1, 2, 3, 4];
callback(&mut my_vec);
}
That results in these errors:
error[E0161]: cannot move a value of type dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>): the size of dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>) cannot be statically determined
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^ cannot move out of borrowed content
Why is calling a FnOnce
a move? What am I missing here?
Why is calling a
FnOnce
a move?
Because that's the definition of what makes a closure FnOnce
:
extern "rust-call" fn call_once(self, args: Args) -> Self::Output
// ^^^^
Contrast this to FnMut
and Fn
:
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output
// ^^^^^^^^^
extern "rust-call" fn call(&self, args: Args) -> Self::Output
// ^^^^^
See also:
You probably want
pub fn call_something(callback: impl FnOnce(&mut Vec<i32>))
or
pub fn call_something<F>(callback: F)
where
F: FnOnce(&mut Vec<i32>),
These are identical. They both take ownership of the closure, which means that you can call the closure and consume it in the process.
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