遇见Safe与Unsafe
源-meet-safe-and-unsafe Commit: a08085479b674bcac6e41bdc00dbee798ea9854e
不必担心底层实现细节是一件很棒的事。谁会关心空元组占用多少空间呢?可惜有时这很重要,我们需要关注它。性能是开发人员开始关注实现细节的最常见原因,但更重要的是,当与其他语言交互,或直接涉及硬件、操作系统时,这些细节可能关系到程序的正确性。
在一个安全的编程语言中,当实现细节开始变得重要时,程序员通常有三个选择:
- 调整代码以让编译器或运行时执行优化
- 采用不地道或更加繁琐的设计来实现所需的实现
- 用一种可以控制这些细节的语言重写实现
对于最后一个选项,程序员们倾向于使用C语言。在与仅提供 C 接口的系统进行交互时,这通常是必须的。
不幸的是,C 语言相当地不安全(这有时是有充分理由的),并且当试图与另一种语言进行互操作时,这种不安全性会被放大。你必须确保 C 和其他语言就正在发生的事情达成一致,并且不互相干扰。
但这与 Rust 有什么关系呢?
好吧,与 C 不同,Rust 是一种安全的编程语言。
但是,像 C 一样,Rust 是一种不安全的编程语言。
更准确地说,Rust 是同时包含安全和不安全的编程语言。
Rust可以被认为是两种编程语言的结合:Safe Rust 和 Unsafe Rust。顾名思义,Safe Rust 是安全的,Unsafe Rust 则不安全。事实上,Unsafe Rust 让我们可以做一些非常不安全的事情。 Rust 作者会恳求你不要做,但无论如何我们都会做。
Safe Rust 是真正的 Rust 编程语言。如果你只是编写Safe Rust,你将永远不必担心类型安全或内存安全。你永远不必忍受悬空指针,释放后使用或任何其他类型的未定义行为。
标准库还为您提供了足够的实用工具,您可以用纯正地道的 Safe Rust 编写高性能的应用程序和库。
但也许你想和另一种语言交互;也许你正在编写一个标准库没有暴露的底层抽象;也许你就正在编写标准库(Rust 标准库百分之百由 Rust 编写);也许你需要做一些类型系统不能理解的事情,调整一些二进制位。也许你需要 Unsafe Rust。
Unsafe Rust 与 Safe Rust 完全相同,具有相同的规则和语义。它只是允许你额外做一些绝对不安全的事情(我们将在下一节中定义)。
这种分离的价值在于我们可以像 C 一样,获得不安全语言的好处——对实现细节的低级别控制——却避免了尝试将其与完全不同的安全语言集成的大多数问题。
仍然存在一些问题——最值得注意的是,我们必须了解类型系统假设成立的一些性质,并时刻注意与 Unsafe Rust 交互的任何代码都要保持这些性质不被破坏。这就是本书的目的:告诉你类型系统做了哪些假设,应该如何处理它们。