Создание системы обратного вызова с использованием замыканий
Я пытаюсь сделать что-то вроде "системы обратного вызова". Например, в нем есть окно и пара кнопок. Окно устанавливает обратные вызовы для каждой кнопки. Оба обратных вызова должны изменить состояние окна. Компилятор не позволяет захватывать&self
в моих замыканиях / обратных вызовах, и я не знаю, как заставить это работать.
Есть ли какие-то общие шаблоны для обратных вызовов, которым я должен следовать?
Это простой пример, поскольку все компоненты имеют одинаковый срок службы. Что если компоненты имеют разные сроки службы?
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();
}