认识安全与不安全

safe and unsafe

如果不必担心底层实现细节,那该多好。谁会在乎空元组占用多少空间? 然而,有时这很重要,我们需要关注它。 开发人员开始关注实现细节的最常见原因是性能,但更重要的是,在直接与硬件、操作系统或其他语言交互时,这些细节可能会成为正确性的问题。

当实现细节在安全的编程语言中变得重要时,程序员通常有三种选择

  • 调整代码以鼓励编译器/运行时执行优化
  • 采用更不符合习惯用法或更繁琐的设计来获得所需的实现
  • 用一种允许你处理这些细节的语言重写实现

对于最后一种选择,程序员倾向于使用的语言是 *C*。 这通常是与仅声明 C 接口的系统交互所必需的。

不幸的是,使用 C 非常不安全(有时是有充分理由的),并且在尝试与另一种语言进行互操作时,这种不安全性会被放大。 必须注意确保 C 和另一种语言对正在发生的事情达成一致,并且它们不会互相干扰。

那么这对 Rust 来说意味着什么呢?

与 C 不同,Rust 是一种安全的编程语言。

但是,与 C 一样,Rust 也是一种不安全的编程语言。

更准确地说,Rust *包含* 安全和不安全的编程语言。

可以将 Rust 视为两种编程语言的组合:*安全 Rust* 和 *不安全 Rust*。 顾名思义,这些名称的含义正是它们所表达的:安全 Rust 是安全的。 不安全 Rust 则,嗯,不安全。 事实上,不安全 Rust 让我们可以做一些 *真正* 不安全的事情。 Rust 作者会恳求你永远不要做的事情,但我们还是会做。

安全 Rust 是 *真正的* Rust 编程语言。 如果你编写的都是安全 Rust,那么你永远不必担心类型安全或内存安全。 你永远不会遇到悬空指针、释放后使用或任何其他类型的未定义行为(又称 UB)。

标准库还为你提供了开箱即用的足够实用程序,让你能够用纯粹的惯用安全 Rust 编写高性能的应用程序和库。

但也许你想与另一种语言进行交互。 也许你正在编写一个标准库没有公开的底层抽象。 也许你正在 *编写* 标准库(它完全是用 Rust 编写的)。 也许你需要做一些类型系统无法理解的事情,而只是 *摆弄一些该死的位*。 也许你需要不安全 Rust。

不安全 Rust 与安全 Rust 完全一样,具有所有相同的规则和语义。 它只是让你可以做一些 *额外* 的绝对不安全的事情(我们将在下一节中定义)。

这种分离的价值在于,我们获得了使用像 C 这样的不安全语言的优势——对实现细节的低级控制——而没有试图将其与完全不同的安全语言集成时出现的大多数问题。

仍然存在一些问题——最值得注意的是,我们必须了解类型系统所做的假设,并在与不安全 Rust 交互的任何代码中对其进行审核。 这就是本书的目的:教你了解这些假设以及如何管理它们。