您可以在堆栈上使用结构。这具有确定性破坏。您甚至可以使用std.typecons.RefCounted对其进行重新计数。如果要保证析构函数运行,请不要在堆上使用结构。目前,我认为如果将结构体的析构函数放在堆上,它们就不会运行,因为 GC 没有它需要这样做的信息(这应该在未来虽然)。
但是如果你坚持把它放在一个类的堆上,并且你想显式地销毁这个对象,那么你可以调用clear
它:
clear(obj);
这将调用对象的析构函数,然后将其置于无效状态,之后任何尝试使用它的东西都会崩溃(IIRC,虚拟表被清零)。但实际上并没有释放内存。那是GC的工作。并且不要使用delete
. 它将被弃用。我实际上很惊讶它还没有,因为它已经计划了很长时间来摆脱它。
当然,一种选择是使用显式函数来调用以释放资源。这是否是一个好主意取决于你在做什么。但无论如何,类是由 GC 收集的,而不是在您选择时释放。
正在对自定义分配器进行工作,这将为您提供更多关于如何分配类的选项,其中一个可能允许您对类进行更具确定性的破坏,但这还没有准备好。
如果你感觉很疯狂,你可以使用std.typecons.scoped,它取代了即将被弃用的类型修饰符scope
(尽管scope
在其他情况下仍然存在 - 例如scope
语句)。它将一个类放在堆栈上。但这是不安全的(这就是为什么scope
在这种情况下会消失),如果要将对象粘贴在堆栈上,您可能还不如只使用结构。
编辑:您也可以使用malloc
andfree
与std.conv.emplace将对象放入非 GC 分配的内存块中,就像在 C++ 中一样,但我认为您必须显式调用析构函数才能获取它运行,因为free
不了解析构函数(它是一个 C 函数)。这将具有使内存与资源一起消失的优势(而clear
在 GC 堆上的对象上使用只会破坏对象的内容,而不是释放内存),但我不知道这会让你买多少clear
在 GC 分配的对象上使用。
但是,您可以创建一个类似于为您new
执行malloc
and的自由函数,然后创建一个类似于调用析构函数的自由函数 and ,这将给您与 C++ 相同的情况。事实上,我想知道这是否足以使它成为标准库。不过,这可能最终会出现在自定义分配器中。所以,如果在不久的将来,你可以使用自定义分配器来做类似的事情,我一点也不感到惊讶emplace
delete
free
auto obj = customAllocObj.create!MyObj(args);
//Do stuff...
customAllocObj.destroy(obj);
而且我认为这将很好地解决您的问题,因为这与您在 C++ 中所拥有的基本相同,只是使用库函数而不是使用内置的new
和delete
. 我想我会在新闻组上提出来。我希望至少有一些人会喜欢这样的功能,而且这似乎与自定义分配器很相配。