Storing Fn in vec

struct FnStorage<F>
where F: std::ops::Fn() + 'static
{
        fns: Vec<Box<F>>,
}
impl<F> FnStorage<F>
where F: std::ops::Fn() + 'static
{
    fn init()->Self
    {
        let mut fns = Vec::<Box<F>>::new();
        for i in 0..10
        {
            let a_fn = || {println!("Im Fn:{}",i)};
            fns.push(Box::new(a_fn));//Here compiler complains about mismatch in types
        }
        FnStorage{fns}
    }
}

Really puzzled by this.
I thought closures implement Fn trait, so if I have that trait boxed I could store it in a vec. But I'm doing something wrong. Can somebody point me in to the right direction?
Thanks

Each closure has its own unique type, but Vec<F> requires all its elements to have the same type. So you can't put multiple different closures into it.

However, you can use trait objects to create a vector that stores pointers to multiple types that implement the same trait. Trait objects types start with the dyn keyword, like this:

struct FnStorage {
        fns: Vec<Box<dyn Fn()>>,
}

impl FnStorage {
    fn init()->Self
    {
        let mut fns = Vec::<Box<dyn Fn()>>::new();
        for i in 0..10
        {
            let a_fn = move || {println!("Im Fn:{}",i)};
            fns.push(Box::new(a_fn));
        }
        FnStorage{fns}
    }
}

Playground

2 Likes