Trait std::panic::UnwindSafe1.9.0[][src]

pub auto trait UnwindSafe { }
Expand description

表示 Rust 中 “panic safe” 类型的标记 trait。

默认情况下,此 trait 对许多类型都实现,并且在推断实现时类似于 SendSync traits。 这个 trait 的目的是编码哪些类型可以安全地越过 catch_unwind 边界,而不必担心 unwind 安全。

什么是 unwind 安全性?

在 Rust 中,如果一个函数可以 0panics 或调用一个传递 panics 的函数,则可以提前 “return”。 这种控制流并非总是可以预期的,并且有可能通过结合以下两个关键组件而导致细微的错误:

  1. 当线程 panics 时,数据结构体处于暂时无效状态。
  2. 然后,随后观察到该损坏的不变量。

通常,在 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 的任何封闭变量。

Implementations on Foreign Types

Implementors

Auto implementors