【RUST】Ch15 智能指针(Smart Pointers)
指针,通常是指一个包含内存地址的变量。这个地址通常引用,或者说指向其他数据。在Rust中,最常见的指针类型就是引用(reference),其已经在第4章中介绍。引用会被 & 符号所标明,同时从他们所指向的数据中借出值。跟引用指向的数据相比较,引用并没有任何特殊能力。 同时,引用也没有我们通常所使用的指针所带来的开销。
在另一方面,智能指针不仅仅是一种行为看起来像指针的数据结构,也同时拥有额外的元数据和能力。智能指针的概念不仅仅只存在于rust中,它起源于C++,也存在于其他语言中。 在Rust中,标准库中定义的不同的智能指针的能力超出了引用所提供的能力。我们在本章中学习的‘引用计数’智能指针就是一个列子。这种指针通过保存拥有者的总数来使得你有多个数据拥有者,同时,当没有拥有者时,则清楚数据.
在rust中,我们使用了拥有者和借出的概念。引用和智能指针的一个额外区别是,引用仅仅是用来借数据的指针,相反的,在很多场景中,智能指针对他们指向的数据有拥有权
在本书中,我们已经遇到过几种智能指针来,比如第八章中的String和Vec<T>,虽然当时我们还没有把它们叫做智能指针。这两种其实都是智能指针,因为它们拥有自己的内存且允许你操作它们。它们也拥有一些元数据(比如容量),并且额外的能力或者约束(比如String确保了它的内容一定是合法的UTF-8)
智能指针一般都通过结构体来实现。与普通的结构体的区别是,智能指针实现了Deref和Drop特征。Deref特征使得一个智能指针的实列的行为跟引用一致,这样使得在引用上工作的代码,移植到智能指针后依然适用。Drop特征则允许你在智能指针的实列在界限外能够自定义一些行为。在本章中,我们会讨论上述两个特征并展示为什么他们对智能指针如此重要。
Rust中,使用智能指针是一种常见的设计模式。本章中并不会覆盖智能指针的每个方面,有很多库实现了自己的智能指针,当然你也可以自己实现。本章会覆盖标准库中的大多数常见的智能指针:
- Box<T> 用于在堆上分配值
- Rc<T> 开启多个ownership的引用计数类型
- Ref<T>和RefMut<T>, 通过RefCell<T>访问,一种在运行时而不是编译时强制借出规则。
除此之外,我们也会涉及到内部可变性模式,用于暴露一个改变内部值到API。我们也会讨论引用循环:引用循环如何导致内存泄露以及如何防止。
让我们开始吧。