當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Rust Drop用法及代碼示例


本文簡要介紹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!

即使我們刪除了 HasTwoDropDrop 的實現,它的字段的析構函數仍然被調用。這將導致

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

CopyDrop 是互斥的

您不能在同一類型上同時實現 Copy DropCopy 的類型會被編譯器隱式複製,因此很難預測析構函數何時以及多久執行一次。因此,這些類型不能有析構函數。

相關用法


注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Trait core::ops::Drop。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。