Ich versuche, so etwas wie ein "Rückruf-System" zu machen. Zum Beispiel gibt es ein Fenster und ein paar Knöpfe darin. Das Fenster legt Rückrufe für jede Schaltfläche fest. Beide Rückrufe sollten den Status des Fensters ändern. Der Compiler erlaubt nicht, &self
in meinen Schließungen/Rückrufe zu erfassen, und ich weiß nicht, wie es funktioniert.Erstellen eines Rückrufsystems mit Schließungen
Gibt es allgemeine Muster für Rückrufe, denen ich folgen sollte?
Dies ist ein einfaches Beispiel, da alle Komponenten die gleiche Lebensdauer haben. Was ist, wenn die Komponenten unterschiedliche Lebensdauern haben?
struct Button<'a> {
f: Option<Box<Fn() + 'a>>,
}
impl<'a> Button<'a> {
fn new() -> Button<'a> { Button { f: None } }
fn set<T: Fn() + 'a>(&mut self, f: T) { self.f = Some(Box::new(f)); }
fn unset(&mut self) { self.f = None; }
fn call(&self) { match self.f { Some(ref f) => f(), None =>() } }
}
struct Window<'a> {
btn: Button<'a>,
//btns: Vec<Button<'a>>,
}
impl<'a> Window<'a> {
fn new() -> Window<'a> {
Window { btn: Button::new() }
}
fn hi(&mut self) { // self is mutable
println!("callback");
}
fn run(&mut self) {
// Compile error: cannot infer an appropriate lifetime for
// capture of `self` by closure due to conflicting requirements
self.btn.set(|| self.hi()); // How to make it work?
self.btn.call();
self.btn.unset();
}
}
fn main() {
let mut wnd = Window::new();
wnd.run();
}
Ebenfalls relevant: http://stackoverflow.com/questions/32044301/cannot-pass-self-as-callback-parameter-due -zu-doppelt-leihen – Shepmaster