You are going to run into immediate problems with this line:
self.btn.set(|| self.hi());
Here, you need to borrow self
as mutable in order to modify btn
. You are also trying to borrow self
as mutable in the closure. This is going to immediately run into 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 the the memory-safety guarantees of the language.
Also, conceptually you are trying to set up a cycle of references - the Window
knows about Button
and Button
knows about Window
. While this is possible, it often isn't what you want. Once the references have a cycle, it's very hard to disentangle them. You can also search other questions that ask about creating graphs in Rust (as opposed to trees) to see similar issues other people have had.
Ideally, you can structure your code as a tree. Here, I chose that 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();
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…