智能指针
指针 是一个通用概念,指一个包含内存地址的变量。这个地址指向一些其他的数据。在 Rust 中最常见的指针类型是引用,你已经在第 4 章学习过它。引用用 &
符号表示,并借用它们所指向的值。它们除了引用数据之外没有任何特殊的功能,也没有任何开销。
另一方面,智能指针 是行为类似指针的数据结构,但它们还具有额外的元数据和功能。智能指针的概念并非 Rust 独有:智能指针起源于 C++,也存在于其他语言中。Rust 在标准库中定义了各种智能指针,它们提供了超出引用所提供的功能。为了探索这个通用概念,我们将查看几个不同的智能指针示例,包括一个引用计数智能指针类型。这个指针允许通过跟踪所有者的数量,让数据拥有多个所有者,并且在没有所有者时清理数据。
Rust 的所有权和借用概念,使得引用和智能指针之间存在另一个区别:虽然引用只是借用数据,但在许多情况下,智能指针拥有它们所指向的数据。
虽然当时我们没有这样称呼它们,但我们已经在本书中遇到了一些智能指针,包括第 8 章的 String
和 Vec<T>
。 这两种类型都算作智能指针,因为它们拥有一些内存并允许你操作它。它们还具有元数据和额外的功能或保证。例如,String
将其容量存储为元数据,并且具有额外的能力来确保其数据始终是有效的 UTF-8。
智能指针通常使用结构体实现。与普通结构体不同,智能指针实现了 Deref
和 Drop
trait。 Deref
trait 允许智能指针结构体的实例表现得像引用,因此你可以编写代码来处理引用或智能指针。Drop
trait 允许你自定义当智能指针实例超出作用域时运行的代码。在本章中,我们将讨论这两个 trait,并演示它们对智能指针的重要性。
鉴于智能指针模式是在 Rust 中经常使用的通用设计模式,本章不会涵盖所有现有的智能指针。许多库都有自己的智能指针,你甚至可以编写自己的智能指针。我们将涵盖标准库中最常见的智能指针。
Box<T>
用于在堆上分配值Rc<T>
,一个引用计数类型,允许拥有多个所有者Ref<T>
和RefMut<T>
,通过RefCell<T>
访问,这是一种在运行时而不是编译时强制执行借用规则的类型
此外,我们将讨论内部可变性模式,其中不可变类型公开用于修改内部值的 API。我们还将讨论引用循环:它们如何泄漏内存以及如何防止它们。
让我们深入了解一下!