返回介绍

8.4 析构

发布于 2024-10-13 11:25:31 字数 1861 浏览 0 评论 0 收藏 0

通过实现 Drop 特征自定义析构函数(destructor)。超出作用域,析构函数会在值释放前自动调用。

struct Data {}

impl Drop for Data {
  fn drop(&mut self) { println!("drop!"); }
}

/* ---------------------------------------- */

fn main() {
  {
    let _d = Data{};
  }

  println!("exit");
}

通常无需定义析构函数,编译器会自动生成 胶水函数 (drop glue)递归释放所有字段成员。即便自定义了析构函数,也无需手工释放字段成员,应专注于关闭文件和网络套接字等清理任务。

结构按字段定义顺序释放,而本地变量则按定义反向顺序释放。实际上,我们的逻辑不应该依赖这种顺序。

struct Data {}

impl Drop for Data {
  fn drop(&mut self) { println!("drop!"); }
}

/* ---------------------------------------- */

struct Demo {
  d: Data,
  b: Box<i32>,
  s: String
}

/* ---------------------------------------- */

fn main() {

  {
    let _d = Demo{
      d: Data{},
      b: Box::new(100),
      s: String::from("abc"),
    };
  }

  println!("exit");
}
(gdb) disass
Dump of assembler code for function demo::main:

  call   0x55555555afe0 <drop_in_place<demo::Demo>>

End of assembler dump.


(gdb) disass 0x55555555afe0
Dump of assembler code for function drop_in_place<demo::Demo>:

   call   0x55555555afc0 <drop_in_place<demo::Data>>
   call   0x55555555b0d0 <drop_in_place<alloc::boxed::Box<i32>>>
   call   0x55555555b060 <drop_in_place<alloc::string::String>>
   
End of assembler dump.

不允许直接调用析构函数,以 drop 函数代替。

该函数实质就是个空函数,通过参数转移所有权来达到释放目的。也因此对实现了 Copy 特征的对象无效。

d.drop();
  ^^^^ explicit destructor calls not allowed
fn main() {
  let d = Demo{
    d: Data{},
    b: Box::new(100),
    s: String::from("abc"),
  };

  // 未出作用域,提前释放!
  std::mem::drop(d);

  println!("exit");
}

不能同时为一个目标实现 Copy 和 Drop。编译器认为需要自定义 “清理” 操作,必然不能按位复制。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文