在 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 程式至關重要。