Trait std::panic::UnwindSafe
1.9.0 · source · 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 的更多信息,请参见 相关的 RFC。
什么是 UnwindSafe
?
现在我们已经了解了 Rust 中的 unwind 安全性,了解此 trait 所代表的意义也很重要。
如上所述,见证不变量被破坏的一种方法是通过这个模块中的 catch_explode
函数,因为它允许捕获一个 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
的任何封闭变量。