In this line you will encounter the following problems:
self.btn.set(|| self.hi());
Here you need to take self as mutable to change btn . You are also trying to borrow self as mutable in closure. This will immediately cause problems because Rust does not allow you to have multiple mutable references to the same object (known as aliasing). This is a fundamental part of language memory security guarantees.
In addition, you are conceptually trying to set up a link loop - Window knows about Button and Button knows about Window . While this is possible, often this is not what you want. Once links have a loop, it is very difficult to untangle them. You can also find other questions that ask about creating graphs in Rust (as opposed to trees) to see similar problems that other people had.
Ideally, you can structure your code like a tree. Here, I chose what Button can know about Window , but not vice versa:
struct Button<'a> { f: Option<Box<FnMut() + 'a>>, } impl<'a> Button<'a> { fn new() -> Button<'a> { Button { f: None } } fn set<T: FnMut() + 'a>(&mut self, f: T) { self.f = Some(Box::new(f)); } fn unset(&mut self) { self.f = None; } fn call(&mut self) { match self.f { Some(ref mut f) => f(), None => () } } } struct Window; impl Window { fn hi(&mut self) { println!("callback"); } } fn main() { let mut wnd = Window; let mut btn = Button::new(); btn.set(|| wnd.hi()); btn.call(); btn.unset(); }
Shepmaster
source share