提问人:TheLovelySausage 提问时间:7/27/2022 最后编辑:HerohtarTheLovelySausage 更新时间:7/27/2022 访问量:75
将 defer-lite 与可变结构结合使用时出现意外问题
Unexpected Issue when Using defer-lite in combination with a Mutable Struct
问:
我对 Rust 很陌生,但我遇到了一个奇怪的问题,可能是我误解了 defer-lite 板条箱的工作原理。
如果我有以下代码,那么一切都按预期工作
use defer_lite::defer;
fn main() {
println!("Start");
defer! {
println!("Stop");
}
println!("Interval");
}
我得到了我想要的输出
Start
Interval
Stop
然后,当我尝试包含可变结构时
use defer_lite::defer;
struct Timer {
start:i32, interval:i32, stop:i32
}
fn timer_initialize() -> Timer {
let timer = Timer{start:0, interval:0, stop:0 };
return timer;
}
impl Timer {
fn timer_start(&mut self) { self.start = 1; }
fn timer_interval(&mut self) { self.interval = 2; }
fn timer_stop(&mut self) { self.stop = 3; }
}
fn main() {
let mut timer = timer_initialize();
println!("Start");
timer.timer_start();
defer! {
println!("Stop");
timer.timer_stop();
}
println!("Interval");
// uncommenting this line will cause a compiler error
//timer.timer_interval();
}
一切仍然正常,直到我尝试使用下面的结构方法,此时我将收到编译器错误defer!
timer.timer_interval();
^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
我不确定为什么会这样,如果我使用了 defer-lite 错误
答:
1赞
Chayim Friedman
7/27/2022
#1
这是这个板条箱的局限性。这不能在 Rust 中实现。问题在于,为了完成其工作,需要创建一个 RAII 防护,将清理代码保存为闭包。但是闭包包含对值的可变引用,因此在它被删除之前,您不能再次使用它 - 在作用域的末尾。defer-lite
如果你需要,我会推荐scopeguard板条箱,它也更受欢迎。它为这种情况提供了一个 guard()
函数。它的工作原理如下:
fn main() {
let mut timer = timer_initialize();
println!("Start");
timer.timer_start();
let mut timer = scopeguard::guard(timer, |mut timer| {
println!("Stop");
timer.timer_stop();
});
println!("Interval");
timer.timer_interval();
}
评论
0赞
TheLovelySausage
7/27/2022
哇,这真是一种巨大的解脱,转移到 scopeguard 正是我所需要的
评论
RefCell
中。cargo check
Timer