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 的更多信息,请参见 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 的任何封闭变量。

Implementations on Foreign Types

Implementors

Auto implementors