當前位置: 妍妍網 > 碼農

聊一聊Rust中的參照及其記憶體表現

2024-05-20碼農

Rust 是一門系統程式語言,它克服了傳統語言安全性和效能的均衡問題,提供了獨特的記憶體管理方式。在 Rust 中,參照(references)是理解所有權、借用和生命周期概念的基礎。今天,我們將深入探討 Rust 中的參照及其在記憶體中的表現,並透過詳細的範例來展示這些概念如何在現實編碼中使用。

Rust 參照的記憶體表現

Rust 中的參照有兩種主要形式:不可變參照 &T 和可變參照 &mut T 。兩者在記憶體中通常被表示為指向記憶體地址的指標。由於這些指標的大小等同於 usize 型別,無論是不可變參照還是可變參照,它們在記憶體中的大小都是固定的。

透過 std::mem::size_of 函式,我們可以確認上述說法:

#![allow(unused)]
fnmain() {
assert_eq!(std::mem::size_of::<&String>(), 8);
assert_eq!(std::mem::size_of::<&mutString>(), 8);
}

這段程式碼驗證了無論是不可變參照 &String 還是可變參照 &mut String ,它們在記憶體當中的大小均為 8 字節(在 64 位架構上)。

不可變參照記憶體結構

考慮下面的程式碼片段:

#![allow(unused)]
fnmain() {
let s = String::from("Hey");
let r = &s;
}

記憶體中的布局可能如下所述:

Stack Heap
+----------+ +---+---+---+
| | | H | e | y |
+----|-----+ +---+---+---+
|
+--|--------------+
| pointer to heap |
+-----------------+
| &s |
+-----------------+
r (reference)

r 是一個指向堆上數據的指標(具體來說,是指向含有 String 數據的指標)。這說明當我們聲明一個不可變參照時,實質上我們建立了一個指向值的指標。

可變參照記憶體結構

接下來,考慮可變參照。

#![allow(unused)]
fnmain() {
letmut s = String::from("Hey");
let r = &mut s;
}

可變參照 &mut T 在記憶體中的表現與不可變參照類似,都是一個指向具體記憶體位置的指標。不同之處在於,可變參照允許我們修改所指向的數據。

Stack Heap
+----------+ +---+---+---+
| | | H | e | y |
+----|-----+ +---+---+---+
|
+--|--------------+
| pointer to heap |
+-----------------+
| &mut s |
+-----------------+
r (reference, mutable)

這裏的 r 是一個可變參照,指向 s 的數據,允許在生命周期內修改堆上的數據。

參照與堆記憶體的關系

前面的例子裏提到的堆記憶體是我們申請用來儲存 String 數據的空間。不過,參照並不一定總是指向堆記憶體。實際上,它們只是簡單地指向一個記憶體地址,這個地址可能在堆上,也可能在棧上。關鍵在於,參照提供了一種安全的方式來存取這些數據,無論它們位於何處。

指標型別的分類

在 Rust 中,我們通常所討論的指標分為兩類:薄指標(thin pointers)和胖指標(fat pointers)。薄指標僅僅包含一個地址值,而胖指標會攜帶額外的後設資料,比如切片的長度或是特質物件的虛擬方法表(vtable)。

Rust參照實踐範例

現在,我們來透過幾個具體的例子來看看如何使用 Rust 中的參照:

範例1: 使用不可變參照傳遞數據

fnprocess(text: &String) {
println!("Processing text: {}", text);
}
fnmain() {
let my_string = String::from("Hello, Rust!");
process(&my_string);
}

這個簡單的例子演示了如何將一個不可變參照傳給函式,以便在不擁有所有權的情況下讀取 String

範例2: 修改可變參照指向的數據

fnmodify(text: &mutString) {
text.push_str(" More text");
}
fnmain() {
letmut my_string = String::from("Hello, Rust!");
modify(&mut my_string);
println!("Modified string: {}", my_string);
}

在這個例子中,我們傳遞了一個可變參照給函式 modify ,允許它修改原本的字串。

結語

Rust 參照是一種強大的特性,它允許我們安全、高效地處理數據。透過了解和實踐其在記憶體中的表現,我們能夠更好地掌握 Rust 語言,並編寫出可靠且效能優異的程式。隨著我們不斷深入學習,將發現更多精細和高級的用法,進一步提升我們的編碼技巧。

文章精選

「Rust