1 // Rust-101, Part 11: Trait Objects, Box, Lifetime bounds
2 // ======================================================
5 // For now, we just decide that the callbacks have an argument of type `i32`.
6 struct CallbacksV1<F: FnMut(i32)> {
10 /* struct CallbacksV2 {
11 callbacks: Vec<FnMut(i32)>,
14 pub struct Callbacks {
15 callbacks: Vec<Box<FnMut(i32)>>,
19 // Now we can provide some functions. The constructor should be straight-forward.
20 pub fn new() -> Self {
24 // Registration simply stores the callback.
25 pub fn register(&mut self, callback: Box<FnMut(i32)>) {
26 self.callbacks.push(callback);
29 // We can also write a generic version of `register`, such that it will be instantiated with some concrete closure type `F`
30 // and do the creation of the `Box` and the conversion from `F` to `FnMut(i32)` itself.
32 pub fn register_generic<F: FnMut(i32)+'static>(&mut self, callback: F) {
36 // And here we call all the stored callbacks.
37 pub fn call(&mut self, val: i32) {
38 // Since they are of type `FnMut`, we need to mutably iterate.
39 for callback in self.callbacks.iter_mut() {
45 // Now we are ready for the demo. Remember to edit `main.rs` to run it.
47 let mut c = Callbacks::new();
48 c.register(Box::new(|val| println!("Callback 1: {}", val)));
52 let mut count: usize = 0;
53 c.register_generic(move |val| {
55 println!("Callback 2: {} ({}. time)", val, count);
62 // **Exercise 11.1**: We made the arbitrary choice of using `i32` for the arguments. Generalize the data-structures above
63 // to work with an arbitrary type `T` that's passed to the callbacks. Since you need to call multiple callbacks with the
64 // same `t: T`, you will either have to restrict `T` to `Copy` types, or pass a borrow.