本文簡要介紹rust語言中 Trait core::ops::Drop
的用法。
用法
pub trait Drop {
fn drop(&mut self);
}
析構函數中的自定義代碼。
當不再需要某個值時,Rust 會對該值運行“destructor”。不再需要某個值的最常見方式是當它超出範圍時。析構函數可能仍然在其他情況下運行,但我們將重點關注此處示例的範圍。要了解其他一些情況,請參閱有關析構函數的 the reference 部分。
這個析構函數由兩個組件組成:
- 如果為它的類型實現了這個特殊的
Drop
特征,則調用該值的Drop::drop
。 - 自動生成的“drop glue” 遞歸調用該值的所有字段的析構函數。
由於 Rust 會自動調用所有包含字段的析構函數,因此在大多數情況下您不必實現 Drop
。但是在某些情況下它很有用,例如對於直接管理資源的類型。該資源可能是內存,可能是文件說明符,也可能是網絡套接字。一旦不再使用該類型的值,它應該通過釋放內存或關閉文件或套接字來“clean up” 其資源。這是析構函數的工作,因此也是 Drop::drop
的工作。
例子
要查看析構函數的作用,讓我們看一下以下程序:
struct HasDrop;
impl Drop for HasDrop {
fn drop(&mut self) {
println!("Dropping HasDrop!");
}
}
struct HasTwoDrops {
one: HasDrop,
two: HasDrop,
}
impl Drop for HasTwoDrops {
fn drop(&mut self) {
println!("Dropping HasTwoDrops!");
}
}
fn main() {
let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
println!("Running!");
}
Rust 將首先為 _x
調用 Drop::drop
,然後為 _x.one
和 _x.two
調用,這意味著運行它會打印
Running!
Dropping HasTwoDrops!
Dropping HasDrop!
Dropping HasDrop!
即使我們刪除了 HasTwoDrop
的 Drop
的實現,它的字段的析構函數仍然被調用。這將導致
Running!
Dropping HasDrop!
Dropping HasDrop!
您不能自己調用Drop::drop
因為Drop::drop
用於清理一個值,所以在調用該方法後使用該值可能很危險。由於 Drop::drop
不獲取其輸入的所有權,Rust 通過不允許您直接調用 Drop::drop
來防止濫用。
換句話說,如果你試圖在上麵的例子中顯式調用Drop::drop
,你會得到一個編譯器錯誤。
如果你想顯式調用一個值的析構函數,可以使用 mem::drop
。
下單
不過,我們的兩個 HasDrop
中哪一個先掉落?對於結構體,其聲明順序相同:首先是 one
,然後是 two
。如果您想自己嘗試一下,可以修改上麵的 HasDrop
以包含一些數據,例如整數,然後在 Drop
內部的 println!
中使用它。這種行為是由語言保證的。
與結構不同,局部變量以相反的順序刪除:
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping Foo!")
}
}
struct Bar;
impl Drop for Bar {
fn drop(&mut self) {
println!("Dropping Bar!")
}
}
fn main() {
let _foo = Foo;
let _bar = Bar;
}
這將打印
Dropping Bar!
Dropping Foo!
完整規則請參閱the reference。
Copy
和 Drop
是互斥的
您不能在同一類型上同時實現 Copy
和 Drop
。 Copy
的類型會被編譯器隱式複製,因此很難預測析構函數何時以及多久執行一次。因此,這些類型不能有析構函數。
相關用法
- Rust Drop用法及代碼示例
- Rust Drain.as_slice用法及代碼示例
- Rust Drain.as_str用法及代碼示例
- Rust DrainFilter用法及代碼示例
- Rust Drain用法及代碼示例
- Rust DirBuilder.new用法及代碼示例
- Rust DirEntry.metadata用法及代碼示例
- Rust Duration.as_micros用法及代碼示例
- Rust Duration.subsec_nanos用法及代碼示例
- Rust DebugList.entries用法及代碼示例
- Rust Duration.checked_add用法及代碼示例
- Rust DoubleEndedIterator.try_rfold用法及代碼示例
- Rust Div用法及代碼示例
- Rust DirBuilder.recursive用法及代碼示例
- Rust Duration.new用法及代碼示例
- Rust DerefMut用法及代碼示例
- Rust DirBuilder.create用法及代碼示例
- Rust DebugList用法及代碼示例
- Rust DirEntry.path用法及代碼示例
- Rust DebugMap.key用法及代碼示例
- Rust Duration.subsec_micros用法及代碼示例
- Rust DoubleEndedIterator.rfold用法及代碼示例
- Rust DirEntry.file_type用法及代碼示例
- Rust Duration.mul_f64用法及代碼示例
- Rust DebugStruct.finish_non_exhaustive用法及代碼示例
注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Trait core::ops::Drop。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。