智能指针
指针(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)是怎样导致内存泄漏的,以及如何避免它们。
让我们开始吧!