什么时候`std :: process :: exit`可以使用吗?

Tho*_*s W 6 destructor exit rust

文件std::process::exit说:

如果需要干净关闭,建议仅在没有更多析构函数运行的已知点调用此函数.

也许是由于我缺乏系统编程背景,我不知道是否有特定点的析构函数运行,如果我应该关心.我想到的唯一一件事就是对文件(或其他东西)进行写操作,最好将事物保持在干净的状态.

还有什么需要注意的吗?我怀疑在较大,更复杂的程序中使用它是不明智的,但对于小工具来说似乎很方便.

Luk*_*odt 7

简短回答:

  • 而是panic!()几乎在所有情况下使用
  • 你几乎可以确保没有析构函数往左跑,如果......
    • ......你在这个main()职能部门
    • ...你手动处理堆栈包括展开(你可能不是......)
  • 有时你可以在退出程序时忽略析构函数,但是你需要小心!

稍微长一点的解释

[...]小工具似乎很方便.

如果由于不可恢复的错误而要退出程序,建议的方法是panic!().这将展开堆栈(运行所有析构函数)并退出程序并附加其他信息(包括您可以指定的消息字符串).

[...]如果有破坏者留在特定点运行,我是否应该关心.

这里析构函数留给是否有实现的局部变量运行Drop在当前堆栈帧或上述任何堆栈帧.堆栈帧是堆栈存储器中的一个区域,它保存函数调用的所有局部变量(松散地说).函数退出后,丢弃所有局部变量,包括调用实现的所有变量的析构函数Drop.

一些析构函数需要运行的概率随着堆栈的深度而增长("在main()你的当前堆栈帧之间调用了多少函数).因此,每当你不在main()函数中时,很难对此进行推理.


什么时候实施Drop?什么时候忽略它们是错误的.考虑一下i32:当我们退出函数时,我们可以将它留在堆栈内存中,因为它没有任何负面的副作用(暂时忽略了数据安全的特殊情况).但是,有许多类型需要实现Drop.以下是几个类别:

  • 分配堆内存:Box<T>,Vec<T>,HashMap<T>,...
  • 保持操作系统的资源:File,Socket,...
  • 返回的句柄:Ref,MutexGuard,...
  • ...

不运行析构函数有不同的效果.第一组可能是最无害的一组:我们会泄漏记忆.但是当你退出程序时,操作系统无论如何都会清理所有这些内存.OS资源几乎相同:文件描述符通常在程序退出时被操作系统删除.

但是有更多的理由来运行析构函数.需要考虑的重点:您经常不知道为什么某些类型会实现Drop,但这些类型确实依赖于它.忽略这一点时可能会发生某些不需要的事情.通常你不会注意到,但有时它会导致严重的问题.

  • @ThomasW 使用 `Result` 将非程序员逻辑错误冒泡回 `main`,然后在 `main` 末尾使用 `std::process::exit` 如果你想控制退出代码到操作系统。使用 `panic!` 来处理程序逻辑错误。 (2认同)