如何处理相互切换的两个 fltk 按钮的生命周期?
How to handle the lifetimes of two fltk buttons that toggle eachother?
我正在尝试创建两个按钮(btn1、btn2)处理事件(简单 'push' 又名 'onclick'),它们应该相互禁用
let mut btn1 = button::Button::new(100, 100, 100, 50, "BTN1");
let mut btn2 = button::Button::new(300, 100, 150, 50, "BTN2");
// handle btn1 click
btn1.handle(move |thisBtn, evt| match evt {
enums::Event::Push => {
clicked(thisBtn, &mut btn2);
true
}
_ => false,
});
// handle btn2 click
btn2.handle(move |thisBtn, evt| match evt {
enums::Event::Push => {
clicked(thisBtn, &mut btn1);
true
}
_ => false,
});
// both buttons should be mutable, or activate/deactivate wont work
fn clicked(thisBtn: &mut button::Button, otherBtn: &mut button::Button) {
thisBtn.deactivate();
otherBtn.activate();
}
error[E0382]: borrow of moved value: `btn2`
--> src\main.rs:18:5
|
6 | let mut btn2 = button::Button::new(300, 100, 150, 50, "BTN2");
| -------- move occurs because `btn2` has type `Button`, which does not implement the `Copy` trait
...
9 | btn1.handle(move |thisBtn, evt| match evt {
| ------------------- value moved into closure here
10 | enums::Event::Push => {
11 | clicked(thisBtn, &mut btn2);
| ---- variable moved due to use in closure
...
18 | / btn2.handle(move |thisBtn, evt| match evt {
19 | | enums::Event::Push => {
20 | | clicked(thisBtn, &mut btn1);
21 | | true
22 | | }
23 | | _ => false,
24 | | });
| |______^ value borrowed here after move
For more information about this error, try `rustc --explain E0382`.
好的,我明白了,我把借来的btn2搬走了,以后就不能用了。所以我试图删除 move
以便 btn2 保留在当前范围内,但失败了:
error[E0373]: closure may outlive the current function, but it borrows `btn2`, which is owned by the current function
这看起来像是 Rc<RefCell<T>>
的经典案例:
let btn1 = Rc::new(RefCell::new(button::Button::new(100, 100, 100, 50, "BTN1")));
let btn2 = Rc::new(RefCell::new(button::Button::new(300, 100, 150, 50, "BTN2")));
let (btn1_clone, btn2_clone) = (Rc::clone(&btn1), Rc::clone(&btn2));
btn1.borrow_mut().handle(move |this_btn, evt| match evt {
enums::Event::Push => {
clicked(this_btn, &mut *btn2_clone.borrow_mut());
true
}
_ => false,
});
btn2.borrow_mut().handle(move |this_btn, evt| match evt {
enums::Event::Push => {
clicked(this_btn, &mut *btn1_clone.borrow_mut());
true
}
_ => false,
});
我正在尝试创建两个按钮(btn1、btn2)处理事件(简单 'push' 又名 'onclick'),它们应该相互禁用
let mut btn1 = button::Button::new(100, 100, 100, 50, "BTN1");
let mut btn2 = button::Button::new(300, 100, 150, 50, "BTN2");
// handle btn1 click
btn1.handle(move |thisBtn, evt| match evt {
enums::Event::Push => {
clicked(thisBtn, &mut btn2);
true
}
_ => false,
});
// handle btn2 click
btn2.handle(move |thisBtn, evt| match evt {
enums::Event::Push => {
clicked(thisBtn, &mut btn1);
true
}
_ => false,
});
// both buttons should be mutable, or activate/deactivate wont work
fn clicked(thisBtn: &mut button::Button, otherBtn: &mut button::Button) {
thisBtn.deactivate();
otherBtn.activate();
}
error[E0382]: borrow of moved value: `btn2`
--> src\main.rs:18:5
|
6 | let mut btn2 = button::Button::new(300, 100, 150, 50, "BTN2");
| -------- move occurs because `btn2` has type `Button`, which does not implement the `Copy` trait
...
9 | btn1.handle(move |thisBtn, evt| match evt {
| ------------------- value moved into closure here
10 | enums::Event::Push => {
11 | clicked(thisBtn, &mut btn2);
| ---- variable moved due to use in closure
...
18 | / btn2.handle(move |thisBtn, evt| match evt {
19 | | enums::Event::Push => {
20 | | clicked(thisBtn, &mut btn1);
21 | | true
22 | | }
23 | | _ => false,
24 | | });
| |______^ value borrowed here after move
For more information about this error, try `rustc --explain E0382`.
好的,我明白了,我把借来的btn2搬走了,以后就不能用了。所以我试图删除 move
以便 btn2 保留在当前范围内,但失败了:
error[E0373]: closure may outlive the current function, but it borrows `btn2`, which is owned by the current function
这看起来像是 Rc<RefCell<T>>
的经典案例:
let btn1 = Rc::new(RefCell::new(button::Button::new(100, 100, 100, 50, "BTN1")));
let btn2 = Rc::new(RefCell::new(button::Button::new(300, 100, 150, 50, "BTN2")));
let (btn1_clone, btn2_clone) = (Rc::clone(&btn1), Rc::clone(&btn2));
btn1.borrow_mut().handle(move |this_btn, evt| match evt {
enums::Event::Push => {
clicked(this_btn, &mut *btn2_clone.borrow_mut());
true
}
_ => false,
});
btn2.borrow_mut().handle(move |this_btn, evt| match evt {
enums::Event::Push => {
clicked(this_btn, &mut *btn1_clone.borrow_mut());
true
}
_ => false,
});