当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Rust Drop用法及代码示例


本文简要介绍rust语言中 Trait std::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 std::ops::Drop。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。