认识 Safe 和 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 交互的任何代码中审核它们。这就是本书的目的:教你了解这些假设以及如何管理它们。