灵巧指针

Smart Pointers

所谓 指针,pointer,是个一般的概念,指的是包含了内存中某个地址的变量。该地址引用,或者说 “指向” 另一数据。Rust 中最常见的指针类别,便是咱们在第 4 章中曾了解过的引用。引用由 & 符号表示,并借用他们指向的值。除了引用数据之外,他们没有任何特殊功能,并且没有开销。

另一方面,灵巧指针,smart pointer 是一种数据结构,其作用类似于指针,但还具有额外的元数据与能力。灵巧指针这个概念,并非 Rust 所独有的:灵巧指针起源于 C++,且在其他语言中也存在。Rust 在标准库中定义了各种智能指针,他们提供了超越引用所提供的功能。为了探讨一般概念,我们将看几个不同的智能指针示例,包括 引用计数,reference counting 智能指针类型。引用计数这种指针,通过追踪数据所有者的数目,实现了允许数据有着多个所有者,在没有所有者剩下时,就清除该数据。

在所有权和借用的概念下,Rust 在引用和智能指针之间还有一个区别:引用只借用数据,而在很多情况下,灵巧指针则 拥有,own 他们所指向的数据。

虽然当时咱们没有这样称呼他们,但在本书中我们已经遇到了一些智能指针,包括第 8 章中的 StringVec<T>。这两种类型都算作灵巧指针,因为他们拥有一些内存,并允许咱们对其进行操作。他们也有元数据和额外的能力或保证。例如,String 将其容量存储为元数据,并有额外的能力来确保其数据将始终是有效的 UTF-8。

灵巧指针通常是使用结构体来实现的。与寻常结构体不同,灵巧指针实现了 DerefDrop 特质。Deref 特质允许灵巧指针结构体实例像引用那样行事,如此咱们便可编写出处理引用或灵巧指针的代码。而 Drop 特质则允许咱们定制在灵巧指针超出作用域时要运行的代码。本章中,咱们将讨论这两种特质,并演示他们为何对灵巧指针很重要。

鉴于灵巧指针模式是 Rust 中频繁用到的一种通用设计模式,本章不会涵盖每个既有灵巧指针。许多库都有自己的灵巧指针,咱们甚至也可以编写自己的灵巧指针。咱们将介绍标准库中最常见的灵巧指针:

  • 用于在内存堆上分配值的 Box<T>
  • Rc<T>,一个引用计数类型,可以实现多重所有权,Rc<T>, a reference counting type that enables multiple ownership;
  • Ref<T>RefMut<T>,通过 RefCell<T> 访问,该类型在运行时而不是编译时执行借用规则检查,Ref<T> and RefMut<T>, accessed through RefCell<T>, a type that enforces the borrowing rules at runtime instead of compile time。

此外,咱们还将讨论 内部可变性,interior mutability 模式,在这种模式下,不可变的类型会暴露出一个用于改变内部值的 API。我们还将讨论引用循环:他们如何泄漏内存以及如何防止他们。

下面就来切入正题吧!

Last change: 2023-12-01, commit: 71a00fa