Hi,
I'm trying to write a callback where I can register multiple callbacks and invoke them all.
The code looks like this:
pub struct Callback<T, F>
where
F: FnMut(T),
{
callbacks: Vec<Box<F>>,
_phantom: PhantomData<T>,
}
impl<T, F> Callback<T, F>
where
F: FnMut(T),
T: Copy,
{
pub fn new() -> Self {
Callback {
callbacks: Vec::new(),
_phantom: PhantomData {},
}
}
pub fn register(&mut self, callback: Box<F>)
where
F: FnMut(T),
{
self.callbacks.push(callback);
}
pub fn register_generic(&mut self, callback: F) {
self.callbacks.push(Box::new(callback));
}
pub fn call(&mut self, val: T) {
let repeat = "*".repeat(20);
println!("{} Begin {}", repeat, repeat);
for callback in self.callbacks.iter_mut() {
// val is move to closure, we need T: Copy
callback(val);
// or
// (&mut *callback)(val);
}
println!("{} End {}", repeat, repeat);
}
}
And playground:
here's the compiler error:
error[E0308]: mismatched types
--> src/main.rs:53:25
|
50 | c.register(Box::new(|val| println!("Callback 1: {}", val)));
| ------------------------------------- the expected closure
...
53 | c.register(Box::new(|val| println!("XXX {}", val)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
|
= note: expected closure `[closure@src/main.rs:50:25: 50:62]`
found closure `[closure@src/main.rs:53:25: 53:54]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: could not compile `callback`
To learn more, run the command again with --verbose.
Why couldn't I invoke another register call with a new boxed closure as parameter?
Thanks