d异常隐藏断定
但是,不是更重要的AssertError,而是抛可怜的异常:
import std.string;
void foo(int i) {
//此时,遗忘了`%s`,但它可能是其他小错误.
assert(i == 42, format("Bad parameter:", i));
}
void main() {
foo(43);
}
用编译时格式串:
assert(myAssumption,format!"%s不工作!"(aa));
最简单方法是让assert(condition, message)先计算消息,以便Ali的示例等价于:
import std.format;
void foo(int i) {
auto __msg = format("坏参数", i);
assert(i == 42, __msg);
}
void main() {
foo(43);
}
这样,如果抛消息式,则永远不会计算断定条件,且程序不会进入无效状态.
不.更改求值顺序会产生深远的影响:
1,先求值消息,副作用可能会改变断定条件的结果.
2,不希望无条件地计算可能昂贵的消息式,即包括断定成立的普通情况.
3,消息式可能依赖失败条件后状态.如恐怖的:
assert(x.trySomething(), x.getLastErrorMsg())
也可这样:
import std.exception : assumeWontThrow;
assert(condition, assumeWontThrow(可能抛式));
它清楚地记录了消息表达式可能抛出的内容.这样,消息表达式引发的异常,不会隐藏错误.
或者创建包装器:
string assertFormat(Args...)(string fmt, Args args)
{
try {
return format(fmt, args);
} catch(Exception ex) {
return "求值错误" ~ ex.toString;
}
}
// 用法:
assert(i == 42, assertFormat("Something %s", functionThatThrows()));
这应该是最佳实践.
浙公网安备 33010602011771号