d比较错误和异常2
原文
我不知道在单元测试块
和合同
中抓错误
行为不一样.
一个反馈是非主线程
.尽管都同意不应抓错误
,但主线程
会这样并打印文章中显示的有用输出
.
如果允许主线程
这样做,也应在非主线程
做同样多(或更少)的事情.否则,无法跟踪线程
.
如果偏执并想尽量少做,至少应复制
串字面到stderr
.类似"线程因错误
退出".然后退出(1)
.
不抓错误的规则,是打印诊断
信息.但此后,不应继续运行程序
.
如果线程
未抓错误并结束程序
,这是运行时
缺陷.
我过去认为不应抛错误
,而是记录错误
(包括调用栈),然后甚至不展开
栈的退出.但是代码至少期望抛错误栈
,这样期望
抓它的代码会中断
.
除非用std.concurrency
,且主线程
查找并接收LinkTerminated
消息(用spawnLinked
启动线程).
void myThread() {
try {
} catch (Exception exc) {
// ...
} catch (Error exc) {
// 报告错误
exit(1); // 退出或其他
}
}
一般,不必继承Error
.用户代码
中抛错误
的最常见的方法是使用assert
,它(有默认
编译器标志)在失败时抛AssertError
.函数合同
和构/类不变量
工作方式相同
可提供必须抛
错误
而不能抛适当异常
代码吗?
这完全是设计API
的问题.如果调用者
在调用函数前检查
某些条件,则可在条件不成立
时抛Error
(或更有可能使用assert
或in
合同来检查它).如果是被调用者
检查,则应抛Exception
(或使用enforce
).
Error
的要点是代码
可假定它不会发生
,如果发生了,则代码无效
.
反映在编译器,则在抛错误
时,会省略清理代码
(可假设它永远不会
).使用Error
目的是最后检查
程序正确性
(因为在到达该点
前未能验证输入
).
如果抛错误
,vibe
应退出.在vibe
代码中总是困扰
我的是,越界
数组错误.我用抛异常
包装器替换了一些数组,因为有时我不想使整个服务器
崩溃,也不想连续验证
数组索引.
只要未抓到可抛或错误
,就应该没问题.简单不标记事物为nothrow
,并不表明它们不会按nothrow
推导.auto
和模板函数
都是推导
出来.
可能很少
会咬到你.但也表明,如果它真的咬人,那真的很难追踪
.
正如Paul
所说,这根据你的API
.如果假定已清理函数输入
,如果超出规范,则可正确
抛错误.
很好示例是区间
函数.你经常会在popFront
方法的开头,看到assert(!empty);
语句.这是普遍接受的,因为如果不检查empty
,则不应调用popFront
.
不应
重试错误,且不应抛错误
.
OutOfMemoryError
不应是错误
,而是异常
.因为无法在分配
前检查分配
是否成功,并且,有些方法可在不关闭
进程就处理内存不足
问题.
可抓并重试
异常.预测失败
,然后抛异常
是可行的.
100%
安全,在具有最小共享内存
的单独进程
中运行它.
你不假定
它,你保证
它.你要向编译器
保证代码不会抛错误
.
但是你并不完美,所以可能犯了错误
,并触发了错误(Error)
.编译器展开栈
并回到主函数
,打印
错误并退出,因此可修复你犯的错误
.
类似段错误
.不应该读取不拥有
的内存(是的,我知道可用段错误
来触发加载内存
,我不是在谈论那种段错误).则当意外段错误
时怎么做?崩溃
程序,然后退出
.这里,默认,语言
会为你提供有关位置
提示,还可在所需位置
抓错误并检查
更多等,来取更多信息
.
但是,我确实向Walter
询问了这个问题,他说要像goto
一样对待抛/抓
错误.
错误
的意义在于可删除
它们来提高效率
.即,就像断定
或检查边界
一样,它们不应成为正常
程序的一部分.而异常
是程序的一部分
,并提供了不同机制来处理错误
.
但是可关闭断定
并使代码运行得更快.我个人从不在某些程序(网络
服务器)上关闭它们,因为代价
不够明显.但如果这些是异常
,就不能关闭
它们.
考虑foreach
循环中区间
的正常流:
// foreach(elem; range)
for(auto r = range; !r.empty; r.popFront) {
auto elem = r.front;
}
如果popFront
和front
两者都调用empty
,则每个循环调用3次empty
,第2次和第3次
调用值相同.有了断定可在不崩溃
程序下就诊断
无效程序,而且还可在需要
时提供完整
性能.
d
的标准库的红黑树
有个遍历整个RBT
并在每个方法调用之前和之后
,验证红黑树invariant
属性的方法.这不是你想要的高性能
代码,因为它完全破坏了复杂性
保证.但是,如果你正在修改
它,可帮助诊断RBT
的问题.这些检查
是为了帮助开发人员
证明代码
是正确的,而不必不断
地证明,对正常使用
是正确的.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现