第 26 天:釋放 Rust 的智能指針,導航點景觀 🚀🦀

https://dev.to/aniket_botre/day-26-unleashing-rusts-smart-pointers-navigating-the-pointerscape-33p8

Day 26: Rust 的智能指針,指引你遨遊指針世界🚀🦀

Rustaceans 啊妳們好!今天,在第 26 天的#100DaysOfCode 中,讓我們踏上探索 Rust 中智能指針的神秘之旅。他們並非普通指針; 它們是數據管理的萬能工具,提供如自動內存魔法和所有權增強等功能。🧙‍♂️✨

智能指針解密

指針基本上是存儲另一個變數的地址的變數。但 Rust 中的智能指針並非普通指針。不,它們是具有獨特技巧的酷酷的小子。與 C++等語言中的傳統指針不同,Rust 的智能指針不僅僅是內存地址。Rust 中的智能指針是不僅指向數據,還具有附加元數據和功能的數據結構。它們就像指針中的詹姆斯·邦德,時髦、精緻,隨時準備行動。它們在所有權,功能和使用案例方面與普通引用不同。

探索一般概念時,我們將看一些智能指針的不同示例。

魔法背後的原因

你問為什麼要使用這些魔法指針呢?好吧,親愛的程式碼人,我們來看看這些智能指針與普通引用有何不同。

Rust 通過所有權和借用的概念,在引用和智能指針之間有著額外的區別:在許多情況下,智能指針擁有其指向的數據,而不僅僅是借用數據。

智能指針中包含了不僅僅是內存地址。它們可以包含元數據(如 Rc中的引用計數)並提供額外功能(如 RefCell中的可變性控制)。

智能指針是讓您以靈活的方式使用 structs 的絕佳工具。它們擁有兩大超能:Deref 和 Drop 特性。Deref 特性使智能指針類似於引用,因此您可以將其與適用於引用的任何代碼一起使用。Drop 特性讓您可以決定當智能指針超出範圍時會發生什麼,因此您可以自由清理或釋放資源。

它們還防止了懸空指針,雙重釋放和內存洩漏的邪惡。此外,它們開辟了普通引用不敢闖入的道路,如內部可變性和共享擁有權。

在指針世界裡的巫師類型

Box:堆疊術師

Box是您存儲堆疊數據的不二之選,非常適合在編譯時無法確定大小的數據結構或大小時使用。它是獨奏藝術家,確保其所指向的數據僅有一個擁有者,提供出色的內存管理。🎭

您將在以下情況下最經常使用它們:

◆ 當您擁有一種類型,其大小無法在編譯時確定,並且您希望在需要確切大小的上下文中使用該類型的值時。

◆ 當您擁有大量數據並且希望轉移所有權但確保在轉移時不會對數據進行復制。

◆ 當您只關心它是一種實現特定特性的類型,而不是具體類型時。

Rc和 Arc:共享擁有大師

Rc及其兄弟 Arc是共享擁有的指揮家。當最後一個音符被演奏完畢時,它們會對引用進行歸還。Arc甚至為多線程添加了線程安全的加料。🎻🎺

當數據需要多個所有者時,Rc是您所需的智能指針。這就像共用度假公寓 – 每個人都可以使用它,但不必承擔全部成本。

使用 std::rc::Rc;

fn main() {
let rc = Rc::new(5);
let rc_clone = Rc::clone(&rc);
println!(“創建 rc_clone 後的計數:{}”, Rc::strong_count(&rc));
// 輸出:創建 rc_clone 後的計數:2
}

在這個片段中,我們創建了一個擁有初始值 5 的引用計數變數 rc。然後,我們創建 rc_clone 作為同一值的另一個持有者。Rc::clone 函數增加了引用計數,Rc::strong_count 告訴我們當前值有多少所有者。

我現在還沒有涉及線程管理,所以不能詳述 Arc。但當我涵蓋線程管理時,一定會包括這一部分。😅

RefCell和 Cell:可變性術士

RefCell是內部可變性(即在 RefCell本身是不可變的情況下修改其所持有的數據)的巫師,通過不可變引用,運行時违反借用规则。同時,Cell是一個更簡單的法師,它為具有 Copy 特性的類型做同樣的事情。要注意,它們危險地與借用規則交互。💃

當您想要內部可變性時,您應使用 RefCell – 即使您擁有對其的不可變借用,也可以修改數據。

使用 std::cell::RefCell;

fn main() {
let data = RefCell::new(5);
*data.borrow_mut() += 1;
println!(“數據 = {}”, *data.borrow());
// 輸出:數據 = 6
}

在這裡,我們創建了一個包含值 5 的 RefCell。然後,我們借用了對 RefCell 內部數據的可變引用,將其加 1 並將其打印出來。請注意,RefCell 會在運行時執行 Rust 的借用規則,所以如果您試圖在已經被借用時請求可變數據,您的程序將會出現 panic。

Cell是 RefCell的簡單版本。它同樣提供內部可變性,但僅限於 Copy 類型。

使用 std::cell::Cell;

fn main() {
let cell = Cell::new(5);
cell.set(10);
println!(“cell = {}”, cell.get());
// 輸出:cell = 10
}

在這個片段中,我們創建了一個值為 5 的 Cell,然後使用 set 將值更改為 10,並使用 get 檢索值。與 RefCell 不同,Cell 不會給您其內部數據的引用,而是將數據放入和取出。

Rust 的內存安全保證使得無法意外創建永不清理的內存(稱為內存洩漏)變得困難,但不是不可能。Rust 無法完全防止內存洩漏,這意味著 Rust 中的內存洩漏是安全的。我們可以看到,使用 Rc 和 RefCell 可以造成內存洩漏:可能會创建引用互相指向的循環。這將導致內存洩漏,因為循環中每個項目的引用計數將永遠不會達到 0,並且值永遠不會被刪除。更多參考訪問:引用循環可能存在內存洩漏

揭示終結

Rust 中的智能指針是提供內存管理安全性和靈活性的強大工具。它們對於編寫堅固且高效的 Rust 程序至關重要,使開發人員能夠構建複雜的數據結構並安全地在線程之間共享數據。有效地理解和使用智能指針對於任何 Rust 程序員來說都是一項關鍵技能。

這次神秘旅程匯集了來自不同來源的見解,呈現了 Rust 中智能指針的全面指南。當我們航向指針世界時,願您的程式碼永遠優雅,您的內存永遠受到良好管理。🚀🧙‍♂️

RustLang #SmartPointers

via DEV Community

January 27, 2024 at 09:30PM

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *