|
|
|
|
@ -1,24 +1,22 @@
|
|
|
|
|
# 智能指针
|
|
|
|
|
|
|
|
|
|
<!-- https://github.com/rust-lang/book/blob/main/src/ch15-00-smart-pointers.md -->
|
|
|
|
|
<!-- commit 56ec353290429e6547109e88afea4de027b0f1a9 -->
|
|
|
|
|
<!-- commit ecef81cbc6f0c2d1c8a67409329b0641258c04c2 -->
|
|
|
|
|
|
|
|
|
|
**指针**(*pointer*)是一个包含内存地址的变量的通用概念。这个地址引用,或 “指向”(points at)一些其它数据。Rust 中最常见的指针是第四章介绍的**引用**(*reference*)。引用以 `&` 符号为标志并借用了它们所指向的值。除了引用数据没有任何其他特殊功能,也没有额外开销。
|
|
|
|
|
**指针**(*pointer*)是一个包含内存地址的变量的通用概念。这个地址会引用,或者说 “指向”(points at)一些其它数据。Rust 中最常见的指针是第四章介绍的**引用**(*reference*)。引用使用 `&` 符号来表示,而且会借用它们指向的值。它们除了引用数据之外没有任何其他特殊功能,也没有额外开销。
|
|
|
|
|
|
|
|
|
|
另一方面,**智能指针**(*smart pointers*)是一类数据结构,它们的表现类似指针,但是也拥有额外的元数据和功能。智能指针的概念并不为 Rust 所独有;其起源于 C++ 并存在于其它语言中。Rust 标准库中定义了多种不同的智能指针,它们提供了多于引用的额外功能。为了探索其基本概念,我们来看看一些智能指针的例子,这包括**引用计数** (*reference counting*)智能指针类型。这种指针允许数据有多个所有者,它会记录所有者的数量,当没有所有者时清理数据。
|
|
|
|
|
另一方面,**智能指针**(*smart pointers*)是一类数据结构,它们的表现类似指针,但是也拥有额外的元数据和功能。智能指针的概念并不为 Rust 所独有;其起源于 C++ 并存在于其它语言中。Rust 标准库中定义了多种不同的智能指针,它们提供了远超引用的功能。为了探索其基本概念,我们来看一些智能指针的例子,这包括**引用计数** (*reference counting*)智能指针类型。这种指针允许数据有多个所有者,它会记录所有者的数量,当没有所有者时清理数据。
|
|
|
|
|
|
|
|
|
|
在 Rust 中因为引用和借用的概念,普通引用和智能指针有一个额外的区别:引用是一类只借用数据的指针,在大部分情况下,智能指针**拥有**它们指向的数据。
|
|
|
|
|
在 Rust 中因为引用和借用的概念,引用和智能指针有一个额外的区别:引用只会借用数据,而智能指针在很多时候**拥有**它们指向的数据。
|
|
|
|
|
|
|
|
|
|
实际上本书中已经出现过一些智能指针,比如第八章的 `String` 和 `Vec<T>`,虽然当时并没有这样称呼它们。这些类型都属于智能指针,因为它们拥有一些数据,并允许你修改这些数据。它们也拥有元数据和额外的功能或保证。例如 `String` 存储了其容量作为元数据,并拥有额外的能力来确保其数据总是有效的 UTF-8 编码。
|
|
|
|
|
智能指针通常使用结构体实现。智能指针不同于普通结构体的地方在于它实现了 `Deref` 和 `Drop` trait。`Deref` trait 允许智能指针结构体实例表现得像引用一样,这样就可以编写既用于引用、又用于智能指针的代码。`Drop` trait 允许我们自定义当智能指针离开作用域时运行的代码。本章会讨论这些 trait 以及为什么它们对智能指针很重要。
|
|
|
|
|
|
|
|
|
|
智能指针通常使用结构体实现。智能指针不同于结构体的地方在于其实现了 `Deref` 和 `Drop` trait。`Deref` trait 允许智能指针结构体实例表现的像引用一样,这样就可以编写既用于引用、又用于智能指针的代码。`Drop` trait 允许我们自定义当智能指针离开作用域时运行的代码。本章会讨论这些 trait 以及为什么对于智能指针来说它们很重要。
|
|
|
|
|
|
|
|
|
|
考虑到智能指针是一个在 Rust 经常被使用的通用设计模式,本章并不会覆盖所有现存的智能指针。很多库都有自己的智能指针而你也可以编写属于你自己的智能指针。这里将会讲到的是来自标准库中最常用的几种:
|
|
|
|
|
考虑到智能指针是一个在 Rust 中经常使用的通用设计模式,本章的内容并不会涉及到所有现存的智能指针。很多库都有自己的智能指针,而且你也可以编写属于你自己的智能指针。这里会讲到标准库中最常用的几种:
|
|
|
|
|
|
|
|
|
|
- `Box<T>`,用于在堆上分配值
|
|
|
|
|
- `Rc<T>`,一个引用计数类型,其数据可以有多个所有者
|
|
|
|
|
- `Ref<T>` 和 `RefMut<T>`,通过 `RefCell<T>` 访问。`RefCell<T>` 是一个在运行时而不是在编译时执行借用规则的类型。
|
|
|
|
|
- `Ref<T>` 和 `RefMut<T>`,它们是通过 `RefCell<T>` 访问的。而 `RefCell<T>` 是一个在运行时而非编译时执行借用规则的类型。
|
|
|
|
|
|
|
|
|
|
另外我们会涉及**内部可变性**(*interior mutability*)模式,这是不可变类型暴露出改变其内部值的 API。我们也会讨论**引用循环**(*reference cycles*)会如何泄漏内存,以及如何避免它们。
|
|
|
|
|
另外我们会讲到**内部可变性**(*interior mutability*)模式,这种模式允许一个不可变的类型暴露出能够修改其内部值的 API。我们也会讨论**引用循环**(*reference cycles*)是怎样导致内存泄漏的,以及如何避免它们。
|
|
|
|
|
|
|
|
|
|
让我们开始吧!
|
|
|
|
|
|