灵巧指针
Smart Pointers
所谓 指针,pointer,是个一般的概念,指的是包含了内存中某个地址的变量。该地址引用,或者说 “指向” 另一数据。Rust 中最常见的指针类别,便是咱们在第 4 章中曾了解过的引用。引用由 &
符号表示,并借用他们指向的值。除了引用数据之外,他们没有任何特殊功能,并且没有开销。
另一方面,灵巧指针,smart pointer 是一种数据结构,其作用类似于指针,但还具有额外的元数据与能力。灵巧指针这个概念,并非 Rust 所独有的:灵巧指针起源于 C++,且在其他语言中也存在。Rust 在标准库中定义了各种智能指针,他们提供了超越引用所提供的功能。为了探讨一般概念,我们将看几个不同的智能指针示例,包括 引用计数,reference counting 智能指针类型。引用计数这种指针,通过追踪数据所有者的数目,实现了允许数据有着多个所有者,在没有所有者剩下时,就清除该数据。
在所有权和借用的概念下,Rust 在引用和智能指针之间还有一个区别:引用只借用数据,而在很多情况下,灵巧指针则 拥有,own 他们所指向的数据。
虽然当时咱们没有这样称呼他们,但在本书中我们已经遇到了一些智能指针,包括第 8 章中的 String
和 Vec<T>
。这两种类型都算作灵巧指针,因为他们拥有一些内存,并允许咱们对其进行操作。他们也有元数据和额外的能力或保证。例如,String
将其容量存储为元数据,并有额外的能力来确保其数据将始终是有效的 UTF-8。
灵巧指针通常是使用结构体来实现的。与寻常结构体不同,灵巧指针实现了 Deref
与 Drop
特质。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>
andRefMut<T>
, accessed throughRefCell<T>
, a type that enforces the borrowing rules at runtime instead of compile time。
此外,咱们还将讨论 内部可变性,interior mutability 模式,在这种模式下,不可变的类型会暴露出一个用于改变内部值的 API。我们还将讨论引用循环:他们如何泄漏内存以及如何防止他们。
下面就来切入正题吧!