Sorry to bother, I read @leudz 's code at Rust Playground again and fixed the problem using box
use std::rc::Rc;
use std::collections::HashMap;
trait FnClone: Fn(usize, usize) -> usize {
fn clone_box(&self) -> Box<dyn FnClone>;
}
impl<T> FnClone for T
where
T: 'static + Fn(usize, usize) -> usize + Clone,
{
fn clone_box(&self) -> Box<dyn FnClone> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn FnClone> {
fn clone(&self) -> Self {
(**self).clone_box()
}
}
fn main() {
let mut h = HashMap::new();
let add1: Box<dyn FnClone> = Box::new(|a: usize, b: usize| -> usize {
a + b
});
let add2: Box<dyn FnClone> = Box::new(|a: usize, b: usize| -> usize {
a + b + 1
});
h.insert("add1", add1);
h.insert("add2", add2);
let mut engine = Engine::default();
for (_name, f) in h.iter() {
let f1 = f.clone();
engine.register_fn(f1);
}
println!("len={}", engine.fs.len());
}
#[derive(Default)]
pub struct Engine {
pub fs: Vec<Rc<Fn(usize, usize) -> usize>>
}
impl Engine {
pub fn register_fn(&mut self, f: impl Fn(usize, usize)->usize + 'static) {
self.fs.push(Rc::new(f));
}
}
This code compiles, but it uses box and treated a closure as a trait FnClone, not very simple. Can my code above get fixed while still using Rc
?