Trait std::panic::UnwindSafe 1.9.0[−][src]
pub auto trait UnwindSafe { }
Expand description
表示 Rust 中 “panic safe” 类型的标记 trait。
默认情况下,此 trait 对许多类型都实现,并且在推断实现时类似于 Send
和 Sync
traits。
trait 的目的是对可以跨越 catch_unwind
边界安全的类型进行编码,而不必担心 unwind 安全。
什么是 unwind 安全性?
在 Rust 中,如果一个函数可以 0panics 或调用一个传递 panics 的函数,则可以提前 “return”。 这种控制流并非总是可以预期的,并且有可能通过结合以下两个关键组件而导致细微的错误:
- 当线程 panics 时,数据结构体处于暂时无效状态。
- 然后,随后观察到该破碎的不变式。
通常,在 Rust 中,很难执行步骤 (2),因为捕获 panic 涉及生成线程 (这又使以后很难看到损坏的不变式) 或在此模块中使用 catch_unwind
函数。
此外,即使见证了一个不变式,在 Rust 中也通常不是问题,因为不存在未初始化的值 (如 C 或 C++ )。
然而,在Rust中,logical 不可变变量被破坏是有可能的,这最终会导致行为 Bug。
Rust 中 unwind 安全性的另一个关键方面是,在没有 unsafe
代码的情况下,panic 不会导致内存不安全。
那是 unwind 安全性的旋风之旅,但是有关 unwind 安全性及其如何应用于 Rust 的更多信息,请参见 associated RFC。
什么是 UnwindSafe
?
现在我们已经了解了 Rust 中的 unwind 安全性,了解此 trait 所代表的意义也很重要。
如上所述,见证不可变变量不变的一种方法是通过此模块中的 catch_unwind
函数,因为它允许捕获 panic,然后重新使用闭包的环境。
简而言之,如果类型 T
无法通过使用 catch_unwind
(捕获 panic) 来轻松地见证破损的不变式,则可以实现 UnwindSafe
。
trait 是自动的 trait,因此可以自动实现为多种类型,并且在结构上也已组成 (例如,如果结构体的所有组件都是 unwind 安全的,则该结构体是 unwind 安全的)。
但是请注意,这不是不安全的 trait,因此该 trait 没有提供简洁的契约。
相反,它旨在作为 “speed bump” 的一部分,以警告 catch_unwind
用户,可能会目击到破碎的不变式,并且可能需要解决这些不变式。
谁实现 UnwindSafe
?
&mut T
和 &RefCell<T>
之类的类型是 unwind 不安全的示例。通常的想法是,默认情况下,可以在 catch_unwind
之间共享的任何可变状态都不是 unwind 安全的。
这是因为很容易看到 catch_unwind
之外的不可变变量,因为像往常一样简单地访问数据。
但是,像 &Mutex<T>
这样的类型是 unwind 安全的,因为它们默认实现中毒。他们仍然可以目击损坏的不变式,但是他们已经提供了自己的 “speed bumps”。
什么时候应使用 UnwindSafe
?
并非意味着大多数类型或函数都不必担心此 trait。
它仅用作 catch_unwind
函数的绑定,如上所述,缺少 unsafe
意味着它主要是建议。
AssertUnwindSafe
包装器结构体可用于强制将 trait 应用于传递给 catch_unwind
的任何封闭变量。