"cannot move a value of type FnOnce" when moving a boxed function
It is unlikely FnBox
becomes stable, but for the time being you can wrap the F: FnOnce(...) -> ...
in an Option<F>
, bind it in a mutable closure and unwrap and call it inside (so it panics if it gets called more than once); the resulting closure can be boxed as Box<FnMut(...) -> ...>
, which you might want to wrap somehow to make sure it only gets used ("called") once.
See (my) boxfnonce
crate.
Here's the FnOnce
trait's definition (simplified a little):
pub trait FnOnce<Args> {
type Output;
fn call_once(self, args: Args) -> Self::Output;
}
To call a FnOnce
closure, you need to be able to move the closure value itself into the invocation. Note that self
has to be the actual closure type; a Box<dyn FnOnce>
is a different type altogether.
Rust 1.35
Box<dyn FnOnce>
is now able to be called; your original code works as-is.
Prior versions
There is a type in the standard library for working around this situation: FnBox
. Unfortunately, it's unstable.
Your alternate choices are:
- Refactor the code so that instead of
Box<FnOnce>
, you preserve the actual closure type. - Use
Box<FnMut>
instead. - Wait for
FnBox
to stabilise. - Switch to a nightly compiler.