documentation of std::process::exit
说:
如果需要干净关闭,建议只在没有更多析构函数运行的已知点调用此函数。
也许是由于我缺乏系统编程背景,我不知道是否有特定点的析构函数,如果我应该关心。我想到的唯一一件事就是对文件(或其他东西)进行写操作,最好将事物保持在干净的状态。
还有其他需要注意的事项吗?我怀疑在较大,更复杂的程序中使用是不可取的,但对于小工具来说似乎很方便。
答案 0 :(得分:7)
panic!()
main()
函数[...]小工具似乎很方便。
如果由于无法恢复的错误而要退出程序,建议的方法是panic!()
。这将展开堆栈(运行所有析构函数)并退出程序并附加其他信息(包括您可以指定的消息字符串)。
[...]如果有一些析构函数在特定点运行并且我应该关心。
如果在当前堆栈帧或上面的任何堆栈帧中存在实现Drop
的局部变量, 析构函数将继续运行。堆栈帧是堆栈存储器中的一个区域,它保存函数调用的所有局部变量(松散地说)。函数退出后,丢弃所有局部变量,包括调用实现Drop
的所有变量的析构函数。
某些析构函数需要运行的概率随着堆栈的深度而增长(“main()
和当前堆栈帧之间调用了多少函数)。因此,无论何时不是,都很难对此进行推理在main()
函数中。
类型何时实施Drop
?如果忽略它们是错误的。考虑i32
:当我们退出函数时,我们可以将它留在堆栈内存中,因为它没有任何负面影响(暂时忽略数据安全的特殊情况)。但是,有许多类型需要实现Drop
。以下是几个类别:
Box<T>
,Vec<T>
,HashMap<T>
,... File
,Socket
,... Ref
,MutexGuard
,... 不运行析构函数会产生不同的效果。第一组可能是最无害的一组:我们会泄漏记忆。但是当你退出程序时,操作系统无论如何都会清理所有这些内存。操作系统资源几乎相同:文件描述符通常在程序退出时被操作系统删除。
但是运行析构函数的理由还有很多。需要考虑的重点:您经常不知道为什么某些类型实现Drop
,但这些类型确实依赖于它。忽略这一点时,某些不需要的东西可以发生。通常你不会注意到,但有时它会导致严重的问题。