1 // Rust-101, Part 11: Trait Objects, Box (WIP)
2 // ===========================================
6 // For now, we just decide that the callbakcs have an argument of type `i32`.
7 struct CallbacksV1<F: FnMut(i32)> {
11 /* struct CallbacksV2 {
12 callbacks: Vec<FnMut(i32)>,
16 callbacks: Vec<Box<FnMut(i32)>>,
20 // Now we can provide some functions. The constructor should be straight-forward.
25 // Registration simply stores the callback.
26 fn register(&mut self, callback: Box<FnMut(i32)>) {
30 // And here we call all the stored callbacks.
31 fn call(&mut self, val: i32) {
32 // Since they are of type `FnMut`, we need to mutably iterate. Notice that boxes dereference implicitly.
33 for callback in self.callbacks.iter_mut() {
39 // Now we are read for the demo.
41 let mut c = Callbacks::new();
42 c.register(Box::new(|val| println!("Callback 1: {}", val)));
46 let mut count: usize = 0;
47 c.register(Box::new(move |val| { count = count+1; println!("Callback 2, {}. time: {}", count, val); } ));
54 // Remember to edit `main.rs` to run the demo.
65 callbacks: Vec<rc::Rc<Fn(i32)>>,
68 // The methods on these clonable callbacks are just like the ones above.
74 fn register(&mut self, callback: rc::Rc<Fn(i32)>) {
78 fn call(&mut self, val: i32) {
79 // We only need a shared iterator here. `Rc` also implicitly dereferences, so we can just call the callback.
80 for callback in self.callbacks.iter() {
86 // The demo works just as above. Our counting callback doesn't work anymore though, because we are using `Fn` now.
88 let mut c = Callbacks::new();
89 c.register(rc::Rc::new(|val| println!("Callback 1: {}", val)));
96 // **Exercise 11.1**: We made the arbitrary choice of using `i32` for the arguments. Generalize the data-structures above
97 // to work with an arbitrary type `T` that's passed to the callbacks. Since you need to call multiple callbacks with the
98 // same `t: T`, you will either have to restrict `T` to `Copy` types, or pass a borrow.