Can I make a boxed FnMut cloneable?


#1

A closure can be cloneable when all variables captured are cloneable:

let foo=Box::new(||{});
let bar=(*foo).clone();

Above code can be compile.

But following code:

let foo:Box<FnMut()>=Box::new(||{});
let bar=(*foo).clone();

cannot.

If I want to return a closure from a function, I have to return Box<FnMut()>, which however is not cloneable.

My question is that is there a way to make Box<FnMut()> cloneable?


#2

Can’t call clone on unsized types, could try something like either;

trait MyFn {
    fn call(&mut self);
    fn box_clone(self: Box<Self>) -> Box<MyFn>;
}
impl<F: 'static + Clone + FnMut()> MyFn for F {
    fn call(&mut self) {
        self()
    }
    fn box_clone(self: Box<Self>) -> Box<MyFn> {
        self.clone()
    }
}

trait MyFnImpl: Clone + FnMut() {}
impl<F: 'static + Clone + FnMut()> MyFnImpl for F {}
fn it() -> impl MyFnImpl {
    || {}
}

fn main() {
    let foo = Box::new(||{}) as Box<MyFn>;
    let mut bar = foo.box_clone();
    bar.call();

    let it = it();
    let mut it2 = it.clone();
    it2();
}

#3

impl Trait in return position is about to become stable so just wait for that to return closures:

fn get() -> impl FnMut() + Clone {
  || ()
}

// If you really want a box 
fn get_boxed() -> Box<impl FnMut() + Clone> {
   Box::new(||())
}

Note that neither of these cases use a trait object.