d必须禁止析构器吗
这里
按GC
拥有对象
构造类对象
来,写这些.
准则:
论坛中看到了以下几个观点.
1,(这是复杂问题.)类没有析构器
;应该叫终结者
.
2,不要在类析构器
中从GC
分配内存.(如,writeln
可能适合简单类型
,但writefln
或format
则不行.)
3,因为可能已析构
,不要使用
类析构器中GC
拥有成员
.
一些事实:
1,不保证
执行类析构器
.这是程序员无法控制的.如,用户可传递
以下命令行选项
,而GC
不会执行类析构器:
$ myprogram "--DRT-gcopt=cleanup:none" ...
(这样启动时,以下示例
运行良好.)
2,即使GC
执行了析构器
的,也不知道何时
准确执行.因此,重要任务交给类析构器
(如关闭
文件)是不行
的.
恐怖:
我刚刚发现一个
大问题.
上面两个准则
(“不要使用
类成员"和"不要分配
”)错过重要的事实,对类结构成员
也要递归这样.如,作为类成员
的结构
也不能在析构器
中分配
内存.
以下程序以core.exception.InvalidMemoryOperationError
结束:
import std.format;
void closeConnection(string s) {
}
struct S {
int id;
~this() {
closeConnection(format!"%s关闭"(id));
}
}
class C {
S s;//类中构
this(int id) {
s = S(id);
}
// @disable ~this();//应禁止
}
void main() {
//只需1就可`显示`阿里环境下错误.
enum N = 1;
foreach (i; 0 .. N) {
auto c = new C(i);
}
}
问题
在遗漏的指导方针
:类
应该@disable
析构器.取消注释
该行时,上面程序正常工作.
当然,应该加上@disable ~this();
作为行为准则.
你怎么看?
不.类析构器
用于清理非垃集
资源.只要坚持这点,就可安全
运行它们.
放入类
的结构
必须正确
运行析构器
,否则,会遇见可怕
的不一致.
如,我不想在类
中禁止RefCounted
结构的析构.
如果关心在构 析构器
中使用垃集
,可用GC.inFinalizer
检查.
我记得几年前,Andrei
提议从语言
中完全删除类析构器
(或终结器
,等等).有点极端
,但反映了你的一般
想法.
关于类析构器
的一个观察是,如果不能清理资源
(运行中不能依赖它,且禁止使用可能已收集
的类引用),则*它们有何实际用途*
,就没用.
类
析构器的默认版无用,非默认时有用.
因此,如果用户使用--DRT-gcopt=cleanup:none
运行程序,碰巧在GC
分配类中有个RefCounted
结构,则搞砸了?
便宜
方法是使用像sprintf
这样的@nogc
方法?
:唔.也许准则
应该是"析构器
必须是@nogc"
.
我同意
.
可观察到:
a)
,对所有类@disable ~this()
,这样可免受
其他编写良好结构成员析构器
影响.一般,此选项
需要该类
的应在释放垃集
内存前调用的清理
函数.
b)
,在每个有可能
在类
中使用的构析构器
中考虑GC.inFinalizer()
(不一定都适用).
c)
,构
中也不要在析构器
中分配垃集
内存.
struct S {
int id;
string closingMessage; // <-- 很贵
this(int id) {
this.id = id;
this.closingMessage = format!"%s关闭"(id);
}
~this() {
// 这里不分配,很好.
closeConnection(closingMessage);
}
}
用@nogc
,如sprintf
很便宜.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现