Drop
特徵
如果值實作了 Drop
,即可在超出範圍時指定要執行哪個程式碼:
struct Droppable { name: &'static str, } impl Drop for Droppable { fn drop(&mut self) { println!("Dropping {}", self.name); } } fn main() { let a = Droppable { name: "a" }; { let b = Droppable { name: "b" }; { let c = Droppable { name: "c" }; let d = Droppable { name: "d" }; println!("Exiting block B"); } println!("Exiting block A"); } drop(a); println!("Exiting main"); }
This slide should take about 8 minutes.
- 請注意,
std::mem::drop
和std::ops::Drop::drop
不同。 - 值超出範圍時,系統會自動捨棄。
- 捨棄值時,如果值實作的是
std::ops::Drop
,系統會呼叫值的Drop::drop
實作。 - 如此一來,無論值是否實作
Drop
,系統都會一併捨棄值的所有欄位。 std::mem::drop
只是一個可接受任何值的空白函式。此函式之所以重要,是能夠取得值的擁有權,因此在其範圍結束時會遭到捨棄。這有利於在值超出範圍之前,明確捨棄這些值。- 如果物件會對
drop
執行某些工作 (例如釋放鎖、關閉檔案等),這就相當實用。
- 如果物件會對
討論要點:
- 為什麼
Drop::drop
不使用self
?- 簡答:如果這樣的話,系統會在 區塊結尾呼叫
std::mem::drop
,進而觸發另一個對Drop::drop
的呼叫並造成堆疊 溢位!
- 簡答:如果這樣的話,系統會在 區塊結尾呼叫
- 請嘗試將
drop(a)
替換為a.drop()
。