Rust内存安全解释


是什么让 Rust 语言成为编写快速、内存安全应用程序的最佳语言之一? Rust 的内存安全功能已融入到语言本身中。

Rust 如何以其他语言无法做到的方式保证内存安全?

Rust 内存安全:本机语言功能
关于 Rust 的内存安全功能,首先要了解的是,它们不是通过库或外部分析工具提供的,这两者都是可选的。 Rust 的内存安全功能已融入该语言中。它们不仅是强制性的,而且是在代码运行之前强制执行的。

在 Rust 中,内存不安全的行为不会被视为 运行时错误,而是被视为 编译器错误。 Rust 中的所有问题(例如释放后使用错误)在语法上都是错误的。此类无效代码永远不会编译,也根本不会投入生产。在许多其他语言(包括 C 或 C++)中,内存安全错误通常只能在运行时发现。

这并不意味着用 Rust 编写的代码完全无懈可击或万无一失。一些运行时问题,例如竞争条件,仍然是开发人员的责任。但 Rust 确实消除了许多常见的软件漏洞利用机会。

内存管理语言(例如C#、Java或Python)几乎完全使开发人员无需进行任何手动内存管理。开发人员可以专注于编写代码和完成工作。但这种便利需要付出一些其他代价,通常是速度或需要更长的运行时间。 Rust 二进制文件可以非常紧凑,默认以机器本机速度运行,并且保持内存安全。

Rust 变量:默认不可变
Rust 新手开发人员首先学到的一件事是,默认情况下所有变量都是不可变的——这意味着它们不能被重新分配或修改。必须将它们明确声明为可变才能更改。

这可能看起来微不足道,但它的最终效果是迫使开发人员充分意识到程序中哪些值需要可变以及何时可变。生成的代码更容易推理,因为它告诉您可以更改什么以及在哪里更改。

默认不可变与常量的概念不同。不可变变量可以被计算,然后在运行时存储为不可变的,也就是说,它可以被计算、存储,然后不被更改。但是,在程序运行之前,常量必须在编译时可计算。许多类型的值(例如用户输入)不能以这种方式存储为常量。

  • C++ 的假设与 Rust 相反:默认情况下,一切都是可变的。您必须使用const关键字来声明事物不可变。您可以const采用 默认使用的 C++ 编码风格 ,但这只会覆盖您编写的代码。
  • Rust 确保所有用该语言编写的程序,现在和将来都默认假定不变性。

Rust 中的所有权、借用和引用
Rust 中的每个值都有一个“所有者”,这意味着在代码中的任何给定点,一次只有一件事可以对值具有完全的读/写控制。所有权可以暂时放弃或“借用”,但这种行为会被 Rust 的编译器严格跟踪。任何违反给定对象的所有权规则的代码都无法编译。

将这种方法与我们在其他语言中看到的方法进行对比。

  • 在 C 语言中,没有所有权:任何东西都可以随时被任何其他东西访问。如何修改事物的所有责任都由程序员承担。
  • 在 Python、Java 或 C# 等托管语言中,所有权规则不存在,但这只是因为它们不需要。对象访问以及内存安全由运行时处理。同样,这是以速度或运行时的大小和存在为代价的。

Rust 的生命周期
Rust 中对值的引用不仅有所有者,还有生命周期——这意味着给定引用有效的范围。在大多数 Rust 代码中,生命周期可以是隐式的,因为编译器会跟踪它们。但对于更复杂的用例,也可以显式注释生命周期。无论如何,尝试访问或修改其生命周期之外的内容或在其“超出范围”之后都会导致编译器错误。这再次防止了所有类别的危险错误通过 Rust 代码进入生产环境。

当您尝试访问理论上已被释放或超出范围的内容时,会出现释放后使用错误或“悬空指针”。这些在 C 和 C++ 中非常常见。 C 在编译时没有正式强制执行对象生命周期。 C++ 有“智能指针”之类的概念来避免这种情况,但默认情况下它们并没有实现;您必须选择使用它们。语言安全成为个人编码风格或机构要求的问题,而不是语言完全确保的事情。

  • 对于 Java、C# 或 Python 等托管语言,内存管理是语言运行时的责任。这是以需要大量运行时间为代价的,有时还会降低执行速度。
  • Rust 在代码运行之前强制执行生命周期规则。

Rust 的内存安全是有代价的
Rust 的内存安全也有成本。第一个也是最大的就是学习和使用语言本身的需要。

切换到一门新语言从来都不是一件容易的事,对 Rust 的常见批评之一是它的初始学习曲线,即使对于经验丰富的程序员也是如此。掌握 Rust 的内存管理模型需要时间和精力。即使在该语言的支持者中,Rust 的学习曲线也是一个不断讨论的话题。

C、C++ 以及所有其他语言都拥有庞大且根深蒂固的用户群,这是他们经常被争论的焦点。他们还拥有大量可以利用的现有代码,包括库和完整的应用程序。不难理解为什么开发人员选择使用 C 语言:围绕它们存在如此多的工具和其他资源。

也就是说,在 Rust 存在的十年左右的时间里,它获得了工具、文档和用户社区,可以更轻松地跟上步伐。第三方“crate库包”或 Rust 库的集合已经非常广泛并且每天都在增长。使用 Rust 可能需要一段时间的重新培训和重新工具,但用户很少会缺乏给定任务的资源或库支持。