智慧指標
指標是一種通用概念,指的是包含記憶體位址的變數。這個位址用來指向其他資料。Rust 中最常見的指標是參考,你在第 4 章已經學過。參考以 & 符號表示,並借用它所指向的值。除了指向資料外,它們沒有任何特殊能力,而且沒有額外開銷。
智慧指標 則是類似指標但也具備額外中繼資料與能力的資料結構。智慧指標的概念並非 Rust 獨有:智慧指標起源於 C++,在其他語言中也存在。Rust 在標準函式庫中定義了多種智慧指標,提供超越參考的功能。為了探討這個一般概念,我們會看看幾個不同的智慧指標例子,包括一種 參考計數 的智慧指標型別。這個指標會追蹤擁有者的數量,讓資料可以有多個擁有者,並在沒有擁有者時清理資料。
在 Rust 中,由於擁有權與借用的概念,參考與智慧指標之間還有另一個差異:參考只會借用資料,但在許多情況下,智慧指標會 擁有 它們所指向的資料。
智慧指標通常以 struct 來實作。與一般的 struct 不同,智慧指標會實作 Deref 與 Drop 特徵。Deref 特徵讓智慧指標 struct 的實例能像參考一樣運作,如此你就能撰寫同時可與參考或智慧指標一起運作的程式碼。Drop 特徵讓你自訂智慧指標實例離開作用域時要執行的程式碼。在本章中,我們會討論這兩個特徵,並示範為什麼它們對智慧指標很重要。
由於智慧指標模式是在 Rust 中常見的通用設計模式,本章不會涵蓋所有現有的智慧指標。許多函式庫都有自己的智慧指標,你甚至可以自行撰寫。我們會介紹標準函式庫中最常見的智慧指標:
Box<T>:在堆上配置值Rc<T>:讓資料可被多重擁有的參考計數型別Ref<T>與RefMut<T>:透過RefCell<T>取得的型別,它在執行期而非編譯期強制借用規則
此外,我們還會介紹 內部可變性 模式,該模式讓不可變型別提供能修改內部值的 API。我們也會討論參考循環:它們如何造成記憶體洩漏,以及如何避免。
讓我們開始吧!