在 Rust 中,每個值都有一個變數,該變數稱為該值的「擁有者」。擁有者的作用是,當擁有者離開作用域時,負責釋放該值所佔用的記憶體. 這確保了記憶體的安全釋放,防止了懸 dangling 指標和記憶體洩漏等問題。
fn main() {
let person = String::from("Roger");
let genious = person;
println!("{}", genious);
}
String::from("Roger") 建立了一個堆積資料型別 String,並由變數 person 擁有其所有權。let genious = person; 表示將 person 的值賦給 genious,這在 Rust 中不是複製(copy),而是所有權轉移(move)。genious 是合法的,因為它現在擁有該 String 的所有權。person,則會造成編譯錯誤,因為它已經不再擁有該資料。| 概念 | 說明 |
|---|---|
| 所有權(Owner) | 每筆堆積資料只能有一個擁有者 |
| Move 行為 | 將所有權從一個變數移轉到另一個變數,原變數失效 |
| Copy vs Move | Copy 型別(如整數)會複製資料;非 Copy 型別(如 String)則會 Move |
| 編譯器檢查 | 編譯器會在編譯時阻止對已失去所有權的變數使用,防止重複釋放記憶體 |
假如你在 println!() 中這樣寫:
println!("{}", person);
將會導致編譯錯誤,還會貼心提醒擁有權已經移動轉到genious:
error[E0382]: borrow of moved value: `person`
--> src\main.rs:15:20
|
13 | let person = String::from("Roger");
| ------ move occurs because `person` has type `String`, which does not implement the `Copy` trait
14 | let genious = person;
| ------ value moved here
15 | println!("{}", person);
| ^^^^^^ value borrowed here after move
這是 Rust 在保護你的記憶體安全,防止「雙重釋放」(Double Free)等錯誤。
| 型別 | 是否會發生 Move? | 說明 |
|---|---|---|
i32、bool |
❌ 不會(它們是 Copy 型別) | 複製資料即可 |
String |
✅ 會發生 Move | 移轉所有權以避免記憶體重複釋放 |
Vec<T> |
✅ 會發生 Move | 同樣屬於堆積資料,遵守所有權系統 |
drop() 函數與擁有權(Ownership)在 Rust 中,每個值都有一個擁有者。當擁有者離開作用域時,Rust 會自動呼叫該值的 drop 函式(如果該型別實作了 Drop trait)。對於像 String 這種擁有堆積分配記憶體的型別,drop 函式的預設行為是釋放該記憶體,防止記憶體洩漏.
fn main() {
let person = String::from("Roger");
drop(person); // 明確手動釋放 person 的資源
let genious = person; // ❌ 錯誤:person 已經被 drop,無法再使用
}
drop() 函數是什麼?drop() 是 Rust 標準函式庫中提供的函數,用來提早釋放資源(記憶體)。drop(person) 時,等同於變數 person 離開作用域時自動被清理。📚 參考文件:std::mem::drop - Rust Docs
Rust 會在變數離開作用域時自動呼叫 drop(),這是 Rust 的記憶體安全保證機制。
fn main() {
let name = String::from("Alice");
}// 當 main 結束,name 會自動被 drop
你也可以用 drop() 手動提前釋放資源,不必等作用域結束。
| 行為類型 | 說明 |
|---|---|
| 自動 drop | 變數離開作用域時自動呼叫,釋放資源 |
| 手動 drop | 使用 drop(var) 明確釋放資源,立即失去所有權 |
| drop 後狀態 | 該變數無法再被使用,會造成編譯錯誤 |
| 與 Copy 的關係 | Copy 型別不需要 drop,無資源釋放需求 |
| 與 Move 的關係 | Move 後的變數會失效,新的變數負責 drop |
在以下程式中:
let person = String::from("Roger");
drop(person);
let genious = person; // ❌ 錯誤!person 的所有權已被釋放
這段會報錯:
error[E0382]: use of moved value: `person`
因為 drop(person) 奪走了所有權並釋放記憶體,接下來的 person 就失效了。
drop() 與所有權的關鍵關係| 比較項目 | 說明 |
|---|---|
drop() 時機 |
可以是自動(離開作用域)或手動(調用 drop) |
| 呼叫後會怎樣? | 變數失效,不能再被使用 |
| 用途 | 提前釋放大量資源或控制釋放順序 |
| 所有權系統的角色 | 確保每個資源有且只有一個負責釋放的所有者 |
Rust 的自動 drop 行為簡化了記憶體管理,防止了記憶體洩漏。drop 函式允許我們自訂資源釋放的行為,而顯式呼叫 drop 則提供了提前釋放資源的靈活性。理解 drop 函式和所有權的關係對於編寫高效且安全的 Rust 程式至關重要。