智能指针
指针(pointer)是一个包含内存地址的变量的通用概念。这个地址会引用,或者说 “指向”(points at)一些其它数据。Rust 中最常见的指针是第四章介绍的引用(reference)。引用使用 & 符号来表示,而且会借用它们指向的值。它们除了引用数据之外没有任何其他特殊功能,也没有额外开销。
另一方面,智能指针(smart pointers)是一类数据结构,它们的行为类似指针,但还拥有额外的元数据和功能。智能指针的概念并不为 Rust 所独有:它起源于 C++,在其他语言中也存在。Rust 标准库中定义了多种不同的智能指针,它们提供了超出引用所能提供的功能。为了探索这一通用概念,我们会看几个不同的智能指针示例,其中包括引用计数(reference counting)智能指针类型。这种指针通过跟踪所有者的数量,让数据能够拥有多个所有者;当所有者都不存在时,它还会清理相应的数据。
在 Rust 中,由于所有权和借用的概念,引用和智能指针之间还有一个额外区别:引用只会借用数据,而智能指针在很多情况下会拥有它们所指向的数据。
智能指针通常使用结构体实现。智能指针不同于普通结构体的地方在于它实现了 Deref 和 Drop trait。Deref trait 允许智能指针结构体实例表现得像引用一样,这样就可以编写既用于引用、又用于智能指针的代码。Drop trait 允许我们自定义当智能指针离开作用域时运行的代码。本章会讨论这些 trait 以及为什么它们对智能指针很重要。
考虑到智能指针模式是在 Rust 中经常使用的一种通用设计模式,本章不会覆盖所有现有的智能指针。很多库都有自己的智能指针,而且你甚至也可以编写自己的智能指针。这里会介绍标准库中最常用的几种:
Box<T>,用于在堆上分配值Rc<T>,一个引用计数类型,其数据可以有多个所有者Ref<T>和RefMut<T>,它们是通过RefCell<T>访问的。而RefCell<T>是一个在运行时而非编译时执行借用规则的类型。
另外我们会讲到内部可变性(interior mutability)模式,这种模式允许一个不可变的类型暴露出能够修改其内部值的 API。我们也会讨论引用循环(reference cycles)是怎样导致内存泄漏的,以及如何避免它们。
让我们开始吧!