3个不稳定版本
0.1.0 | 2021年12月31日 |
---|---|
0.0.1 | 2021年3月5日 |
1438 在 Rust模式 中排名
71,155 每月下载量
在 32 个crate中使用 (直接使用3个)
10KB
118 行
::unwind_safe
通过类似于try-finally的构建器模式实现可读的unwind-safe代码
let mut body_called = false;
let mut finally_called = false;
// Let's imagine some code being run in a context where
// panics do not affect us (`panic::catch_unwind`), or some
// executor running stuff on another thread…
let _ = ::crossbeam::thread::scope(|s| drop(s.spawn(|_| {
let ft = {
::unwind_safe::with_state(())
.try_eval(|_| {
body_called = true;
if ::rand::random() {
panic!();
} else {
42
}
})
.finally(|_| { // <- The point of this crate!
finally_called = true;
})
};
// This is only reached when `try_eval` does not panic, obviously.
assert_eq!(ft, 42);
})));
// Whatever code path was taken, the finally block is always executed
// (that's the point of this crate!).
// From a place that survives the panic (if any), we thus observe:
assert!(body_called);
assert!(finally_called);
具有实际拥有的状态
如果析构函数需要访问 finally
/ 延迟块中的拥有的 State
1 (type State = …:
您选择的类型),
-
您可以将它传递给
::unwind_safe::with_state::<State>
API入口点; -
然后
.try_eval(|state: &mut State| { … })
块将能够通过闭包的参数访问到它的一个 独占 借用(&mut
), -
而
.finally
块将能够通过其自己的闭包参数以拥有的方式访问该状态:.finally(|state: State| { … })
。
1 这种“拥有”状态仍然可能是一个借用,例如,type State = &mut …;
unsafe
代码能否依赖finally
代码总是被执行?
是的!这正是crate的目的,也是为什么它会这样命名:你可以使用这个.finally
模式来确保你的unsafe
代码是可恢复的 ✅
类似于::scopeguard
这类似于::scopeguard::defer!
,但是增加了在finally
/ defer
块中获得所有权的访问能力,同时仍然让主块拥有对它的&mut
引用。
因此,实际上它与::scopeguard::guard
相同!这两个之间唯一的(但至关重要的)区别是代码的可读性:在.try_eval(…).finally(…)
中,可以更明显地看出.finally(…)
部分的代码是在主块代码之后运行的,而在::scopeguard
的API中并不是那么明显(需要知道它是如何工作的)。