我有下面的示例代码,它是其他编程语言中事件驱动的API的标准基础,但在Rust中,借用检查程序阻止它“不能每次多次借用p1
作为mutable”:在Rust中实现多重可变(静态分配,静态分派等)回调等价物的正确方法是什么?
struct Pen {
color_cmyk: u32,
ink: usize,
}
impl Pen {
pub fn new() -> Pen {
Pen {
color_cmyk: 0x80800000,
ink: 20000,
}
}
pub fn write(&mut self, text: &str) -> bool {
if self.ink < text.len() {
return false;
}
self.ink -= text.len();
true
}
}
fn main() {
println!("Hello, world !");
let mut p1 = Pen::new();
p1.write("Hello");
println!("ink: {}, color: {}", p1.ink, p1.color_cmyk);
let mut cb = |text| if p1.write(text) {
println!("{}", text);
} else {
println!("Out of ink !");
};
let mut cb2 = |text| {
p1.write(text);
p1.ink
};
cb("Hello");
cb("World");
println!("{}", cb2("Hello"));
}
error[E0499]: cannot borrow `p1` as mutable more than once at a time
--> src/main.rs:37:23
|
31 | let mut cb = |text| if p1.write(text) {
| ------ -- previous borrow occurs due to use of `p1` in closure
| |
| first mutable borrow occurs here
...
37 | let mut cb2 = |text| {
| ^^^^^^ second mutable borrow occurs here
38 | p1.write(text);
| -- borrow occurs due to use of `p1` in closure
...
45 | }
| - first borrow ends here
该代码可用于,例如,实现两个回调的窗口:一个用于处理键盘事件,而另一个用于处理鼠标事件的,这两者的更新的窗口状态(例如:改变颜色,闭合窗户等)。
我知道,出现在堆栈溢出和其他论坛的其他地方这个问题,但在一般情况下,答案集中在描述问题的原因,很少提出了一个完整的通用解决方案:
- Cannot borrow `x` as mutable more than once at a time
- How to bypass “cannot borrow as mutable more than once”?
- Cannot borrow as mutable more than once at a time
- Passing mutable context into callbacks
- Creating a callback system using closures
- Execute callbacks like as mutable borrowing from cycle
- Callback to mutable self
是什么让你相信你在其他地方看到的答案不是**“完整的通用解决方案”?也许你可以[编辑]你的问题来解释? – Shepmaster
也许我可以直接链接它们 – hdante
换句话说,为什么*不应该被看作是[将可变上下文传入回调](http://stackoverflow.com/q/39089905/155423); [使用闭包创建回调系统](http://stackoverflow.com/q/29540167/155423); [执行回调,如从周期可变借用](http://stackoverflow.com/q/38027461/155423);和[回调可变自我](http://stackoverflow.com/q/39137364/155423)? – Shepmaster