d不用异常.
import std.typecons : Option = Nullable, some = nullable;
alias unwrap = (x) => x.get;
//前面类似rust
Option!int most(string op)(const int[] nums) {
if (nums.length) {
int n = nums[0];
foreach (m; nums[1 .. $]) {
mixin("if (m " ~ op ~ " n) n = m;");
}
return some(n);
} else {
return typeof(return).init;
}
}
alias min = most!"<";
alias max = most!">";
int find_gcd(const int[] nums) {
import std.numeric : gcd;
return gcd(nums.min.unwrap, nums.max.unwrap);
}
unittest {
import std.exception : assertThrown;
import core.exception : AssertError;
assert(find_gcd([3, 5, 12, 15]) == 3);
assertThrown!AssertError(find_gcd([]));
}
结论:
如果nums为空,程序会(一般)因不可抓错误而停止.
冗长解包清楚告诉我们程序在何处有错误因而停止.
因为Option!int和int不是同一类型,不能一起混合.如果忘记处理min/max错误情况,编译器会清楚告诉我们.
因为Option!T与T类型不同,可有自己的错误处理如:
T unwrap_or(T)(Option!T opt, T alternate) { }
这样,来在空针时选择替代.
由于未用异常,可避免运行时成本,可不抛,BetterC也可用,也可有C接口,供其他语言使用.
int broken_find_gcd(const int[] nums) {
import std.numeric : gcd;
return gcd(nums.min, nums.max);
// 错误`std.numeric.gcd`模板不能从参`!()(Option!int, Option!int)`推导函数,可用: ...
}
用这样:
int find_gcd(const int[] nums) nothrow {
import std.numeric : gcd;
return gcd(nums.min.unwrap, nums.max.unwrap);
}
如果d加个nothrow属性,也许很好.
浙公网安备 33010602011771号