我在rosettacode.org上发布了以下代码,用于转换阿拉伯数字和罗马数字的任务.
import std.regex, std.array, std.algorithm;
immutable {
int[] weights = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
string[] symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX",
"V", "IV", "I"];
}
string toRoman(int n) {
auto app = appender!string;
foreach (i, w; weights) {
while (n >= w) {
app.put(symbols[i]);
n -= w;
}
if (n == 0) break;
}
return app.data;
}
int toArabic(string s) {
int arabic;
foreach (m; match(s, "CM|CD|XC|XL|IX|IV|[MDCLXVI]")) {
arabic += weights[symbols.indexOf(m.hit)];
}
return arabic;
}
Run Code Online (Sandbox Code Playgroud)
它曾经工作得很好,但现在我得到一个编译器错误.
错误:模板std.algorithm.indexOf(别名pred ="a == b",R1,R2)if(is(typeof(startsWith!(pred)(haystack,needl e))))与任何函数模板声明都不匹配
根据文档indexOf已被弃用,而countUntil应该被替代使用,但它给了我同样的错误.
很长的故事,但我会尽量保持简短:
std.algorithm.indexOf期望输入范围,它是必须定义的结构类型front,popFront()和empty.对于数组,这些方法在std.array中定义,并通过统一函数调用语法fun(someArray)工作,它允许工作方式相同someArray.fun().
immutable string[]不是输入范围,因为popFront删除了数组的第一个元素,这对于不可变类型是不可行的.这曾经工作的事实是一个错误.
我已经更新了Rosetta Code条目以更改symbols为immutable(string)[].这里,元素symbols是不可变的,但是数组可以被切片并重新分配.例如:
void main() {
immutable string[] s1 = ["a", "b", "c"];
immutable(string)[] s2 = ["d", "e", "f"];
s2 = s2[1..$]; // This is what std.array.popFront does under the hood.
assert(s2 == ["e", "f"]); // Passes.
s2[1] = "g"; // Error: Can't modify immutable data.
s1 = s1[1..$]; // Error: Can't modify immutable data.
s1[1] = "g"; // Error: Can't modify immutable data.
}
Run Code Online (Sandbox Code Playgroud)
immutable string[]是隐式可转换为immutable(string)[]隐式函数模板实例化(通常表示为IFTI;这是用于实例化indexOf模板的东西)不够智能试试这个.