在the documentation案例陈述中,它说:
caseList表示的每个值在这种情况下必须是唯一的 语句;
显示的例子,
case I of
1..5: Caption := 'Low';
6..9: Caption := 'High';
0, 10..99: Caption := 'Out of range';
else
Caption := ;
end
等同于嵌套条件:
if I in [1..5] then
Caption := 'Low';
else if I in [6..10] then
Caption := 'High';
else if (I = 0) or (I in [10..99]) then
Caption := 'Out of range'
else
Caption := ;
所以第一个引用表明它被处理成一个集合(阅读评论here至少有一个人与我在一起)。
现在我知道了部分
其中selectorExpression是序数类型较小的任何表达式 超过32位
与集合的属性相矛盾,因为在集合中提到her:
基类型可以具有不超过256个可能的值,以及它们的值 序数必须介于0到255之间
真正困扰我的是为什么在caseList中拥有唯一值是必要的。如果它等同于if
语句,那么第二个值将不会被测试,因为编译器已经找到了先前的匹配项?
答案 0 :(得分:10)
该文档采用特定 案例语句,该语句相当于特定 if 语句。
通常,任何 case 语句都可以使用相同的方法重写为 if 语句。但是,相反的情况并非如此。
文档使用等效的 if 语句来解释 case 语句的逻辑行为(或语义)。它不是编译器内部工作的表示。
编译器如何处理case语句?
首先请注意这个问题有两个方面。
真正困扰我的是为什么在 caseList 中拥有唯一值是必要的。
消除歧义需要唯一性。如果多个匹配,应该使用哪个caseList语句?
CASE
语句的行为与此类似。)另请参阅下面的[1]
。如果它等同于if语句,则第二个值将不会被测试,因为编译器已经找到了先前的匹配。
[1]
我想指出,这会使代码更难以阅读。使用魔术文字时,此行为是“正常”,但使用const标识符时,这会变得很危险。如果2个不同的consts具有相同的值,则不会立即显示 caseList 匹配的后一个caseList语句将不会被调用。由于简单的 caseList 重新排序,案例陈述也会受到行为改变的影响。
const
NEW_CUSTOMER = 0;
EDIT_CUSTOMER = 1;
...
CANCEL_OPERATION = 0;
case UserAction of
NEW_CUSTOMER : ...;
EDIT_CUSTOMER : ...;
...
CANCEL_OPERATION : ...; { Compiler error is very helpful. }
end;
与集合属性相矛盾
没有矛盾。每个 caseList 值必须唯一的事实并不意味着它必须“像集合一样处理”。那是你不正确的假设。其他人做出同样的假设同样是错误的。
如何检查唯一性约束取决于编译器。我们只能推测。但我猜最有效的方法是维护一个有序的范围列表。遍历每个 caseList 的值和范围,在上面的列表中找到它的位置。如果它重叠,则报告错误,否则将其添加到列表中。
答案 1 :(得分:6)
案例陈述
编译器更喜欢将case语句转换为跳转表
为了使这种可能的重复案例标签不被允许。
此外,编译器不必按照您声明的顺序测试case语句。出于优化原因,它会根据需要重新排序这些元素;因此,即使它不使用跳转表,它仍然不能允许重复的案例标签。
出于同样的原因(并且让程序员在精神上保持理智),case语句不允许堕落。
if statement
一系列(一系列)if语句按声明的顺序处理
编译器将逐个测试它们(并在适当时跳出)
如果if语句不包含重复项,则代码将执行与等效case语句相同的操作,但生成的代码很可能不同。
如果语句永远不会转换为跳转表。
关于集合
原因集限制为256个元素,即集合中的每个元素占用一位空间
256位= 32字节
允许一组中超过256个元素会使内存中的表示过多,从而影响性能。
case语句不使用集合,它只是在其语义中使用set逻辑。