Próbuję stworzyć coś w stylu "systemu wywołań zwrotnych". Na przykład jest tam okno i kilka przycisków. Okno ustawia wywołania zwrotne dla każdego przycisku. Oba wywołania zwrotne powinny zmienić stan okna. Kompilator nie zezwala na przechwytywanie &self
w moich zamknięciach/wywołaniach zwrotnych i nie wiem, jak to zrobić.Tworzenie systemu zwrotnego przy użyciu zamknięć
Czy istnieją jakieś typowe wzorce wywołań zwrotnych, które powinienem śledzić?
Jest to łatwy przykład, ponieważ wszystkie komponenty mają ten sam czas życia. Co się stanie, jeśli składniki mają różne okresy życia?
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();
}
również istotne: http://stackoverflow.com/questions/32044301/cannot-pass-self-as-callback-parameter-due -do-podwójnego wypożyczania – Shepmaster