我正在阅读 Andrei Alexandrescu 的The D Programming Language并在拆解序列中找到了这个块:
...D 假设退出的应用程序将事实上释放与其关联的所有资源,因此它不会调用任何析构函数。
这对内存资源很有效,但是网络套接字、自定义硬件、文件句柄等呢?有没有办法保证我的析构函数总是被调用?或者:D 是否提供了一种更好的方式来处理这些事情(并且我陷入了 C++ 思维模式)?
我正在阅读 Andrei Alexandrescu 的The D Programming Language并在拆解序列中找到了这个块:
...D 假设退出的应用程序将事实上释放与其关联的所有资源,因此它不会调用任何析构函数。
这对内存资源很有效,但是网络套接字、自定义硬件、文件句柄等呢?有没有办法保证我的析构函数总是被调用?或者:D 是否提供了一种更好的方式来处理这些事情(并且我陷入了 C++ 思维模式)?
其他人提到了模块级析构函数,但这并不实用,因为它需要太多的手动维护,而且 D 有一个令人讨厌的怪癖,即具有静态构造函数/析构函数的模块不能循环导入。例如:
模块 A
module A;
import B;
static ~this() {}
void main() {}
模块 B
module B;
import A;
static ~this() {}
试着跑...
% dmd A.d B.d
% ./A
Cycle detected between modules with ctors/dtors:
A -> B -> A
object.Exception@src/rt/minfo.d(331): Aborting!
D 这样做是为了以防你的析构函数碰巧相互依赖,即使它们不依赖。这迫使您对代码进行奇怪的“重构”以解决这个非问题。没有办法告诉 D 实际上没有依赖关系。
处理资源破坏的更好解决方案是尽可能多地尝试和范围。没有需要销毁的全局资源,也不要依赖类终结器来处理任何事情,因为它们不能保证永远运行(Java 也有同样的问题)。
或者,只需像在 C 中那样执行操作:手动关闭。这有点多工作,但真的不是一个大问题。这肯定比与循环进口搏斗要容易。
在这两者之间,一切都被涵盖了,所以假设你对事情如何关闭有发言权是毫无意义的。