我试图在案例切换中包含UTF-8标识符但我收到此错误:
错误:有399个案例,案件范围超过256个案件
D代码:
switch(value)
{
case 'a': .. case 'z':
case 'A': .. case 'Z':
case 0xC0: .. case 0x24F:
为什么编译器会施加这样的限制?为了达到最佳目的?我能克服它吗?
答案 0 :(得分:5)
这样做是为了获得更多空间。
您在此处看到的限制不在规范http://dlang.org/statement中,并且仅适用于编译器中的CaseRangeStatements:我所拥有的版本中的src / dmd / statement.c第3437行:
if (lval - fval > 256)
{ error("had %llu cases which is more than 256 cases in case range", lval - fval);
lval = fval + 256;
}
因此,修复方法是将该范围分成几个部分并将它们放在一起:
switch(value)
{
case 'a': .. case 'z':
case 'A': .. case 'Z':
case 0xC0: .. case 0x14F: // this compiles
case 0x150: .. case 0x24F: // since it is broken up
然后你以同样的方式处理它们。
编译器源代码没有说明为什么会有这样的检查,但github历史记录表明它是为了响应这个错误而提交的:https://issues.dlang.org/show_bug.cgi?id=3139
[s]因此,编译器中的实现细节是为了避免无限循环。[/ s]
编辑:实际上,256检查是在那之前,我读错了补丁,唐除了它之外还添加了一张支票。看起来256件事先于github所以我不知道为什么它被特别添加,但我仍然非常有信心它与循环和内存问题有关,只是编译器实现细节和错误。答案 1 :(得分:2)
摆脱限制的另一种方法是使用委托数组,并使用字符作为选择器选择要调用的方法。然后你的开关看起来有点像这样:
void main(string args[])
{
alias caseProc = void delegate();
caseProc[1024] callTable;
void numberProc(){}
void latinProc(){}
void otherProc(){}
for(auto i = 0; i < callTable.length; i++)
{
if (i >= '0' && i <= '9')
callTable[i] = &numberProc;
else if ((i >= 'a' && i <= 'z') | (i >= 'A' && i <= 'Z'))
callTable[i] = &latinProc;
else
callTable[i] = &otherProc;
}
}
答案 2 :(得分:0)
D中的开关最多只能包含256个案例。你必须改变这样做的整个方式。
if (value >= 'a' && value <= 'z')
{
// ...
}
else if (value >= 'A' && value <= 'Z')
{
// ...
}
else if (value >= 0xC0 && value <= 0x24F)
{
// ...
}
或者像这样,如果你想处理所有相同的情况。
if (value >= 'a' && value <= 'z' || value >= 'A' && value <= 'Z' || value >= 0xC0 && value <= 0x24F)
{
// ...
}