智慧指針
ch15-00-smart-pointers.md
commit 1fedfc4b96c2017f64ecfcf41a0a07e2e815f24f
指針 (pointer)是一個包含記憶體地址的變數的通用概念。這個地址引用,或 “指向”(points at)一些其他數據。Rust 中最常見的指針是第四章介紹的 引用(reference)。引用以 &
符號為標誌並借用了他們所指向的值。除了引用數據沒有任何其他特殊功能。它們也沒有任何額外開銷,所以應用得最多。
另一方面,智慧指針(smart pointers)是一類數據結構,他們的表現類似指針,但是也擁有額外的元數據和功能。智慧指針的概念並不為 Rust 所獨有;其起源於 C++ 並存在於其他語言中。Rust 標準庫中不同的智慧指針提供了多於引用的額外功能。本章將會探索的一個例子便是 引用計數 (reference counting)智慧指針類型,其允許數據有多個所有者。引用計數智慧指針記錄總共有多少個所有者,並當沒有任何所有者時負責清理數據。
在 Rust 中,普通引用和智慧指針的一個額外的區別是引用是一類只借用數據的指針;相反,在大部分情況下,智慧指針 擁有 他們指向的數據。
實際上本書中已經出現過一些智慧指針,比如第八章的 String
和 Vec<T>
,雖然當時我們並不這麼稱呼它們。這些類型都屬於智慧指針因為它們擁有一些數據並允許你修改它們。它們也帶有元數據(比如他們的容量)和額外的功能或保證(String
的數據總是有效的 UTF-8 編碼)。
智慧指針通常使用結構體實現。智慧指針區別於常規結構體的顯著特性在於其實現了 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)會如何洩漏記憶體,以及如何避免。
讓我們開始吧!