Storing a function taking a function in a struct


#1

Hi all,

I would like to store a function (or a closure) in a struct, and this function should take a method implemented on the struct as parameter and use it to store (or update) a generic type defined in the struct. Here is what I want to do:

struct Handler {
  v: Option<T>,
  f: Fn(Fn(T) -> ()),
}

impl Handler {
  fn new(f: Fn(T) -> ())-> Handler { 
    Handler { v: None; f } 
  }

  fn run(&mut self) -> () {
    (self.f)(self.my_cb);
  }

  fn my_cb(&mut self, v: T) {
    self.v = Some(v);
  }
}

fn main() {
  let mut h = Handler::new(|cb| { cb(5); });
  h.run();
}

I removed all type constraints to make the code clear, but I tried a lot of combinations.

I know it’s pretty convoluted :slight_smile: but I keep running into lifetime issues, or “Not Sized” errors, or “Cannot be applied to Trait objects”, etc. I lost count of the experiments I did… :confused:

Thank you for any help, also if it is “it can’t be done”. :slight_smile:


#2

One way would be to use Box<Fn(&Fn(T) -> ())>. You can’t store a bare Fn (because that’s a trait, not a type), so you either have to use generics like F: Fn() -> () or hide Fn behind a pointer (Box or &) and use trait objects.


#3

Thanks! That (especially the & in the inner function) helped make some progress while on my commute this morning. :smiley:

I still had a few re-borrowing problems but I solved them with Arc/RwLock. I’ll keep working on it tomorrow and possibly come back for more suggestions. :smiley: