【发布时间】:2017-06-07 22:02:54
【问题描述】:
当我意识到 D 允许用户将兼容的值强制转换为 enum 并因此可以产生无效的 enum 值时,我感到非常震惊,我认为这在很多层面都是有问题的。
例如,如果我创建了一个库,我在其中公开了一个 enum 类型和一个正在处理它的函数:
module greek;
import std.stdio : writeln;
enum GreekLetters
{
ALPHA,
BETA,
}
void writeGreekLetter(GreekLetters letter)
{
final switch(letter)
{
case GreekLetters.ALPHA:
writeln("\u03B1");
break;
case GreekLetters.BETA:
writeln("\u03B2");
break;
}
}
...然后用户执行以下操作:
import greek : GreekLetters, writeGreekLetter;
void main()
{
writeGreekLetter(cast(GreekLetters)2);
}
...编译器不会抱怨,但显然程序会因(不太好)异常而崩溃:
core.exception.SwitchError@greek(14): No appropriate switch clause found
所以我的问题是:
这是否意味着,我,试图使事情安全(即处理)的图书馆设计师应该避免使用
final switch,并使用其他方法(可能是一个普通的switchdefaultcase)并在那里处理无效的enum状态(返回错误,或抛出异常)?为什么像 D 这样的现代且安全的语言允许我做这样的事情?也就是说,首先允许转换为
enum的主要原因是什么? (从语言设计的角度。)
注意:我知道,
enum可以有一个基本类型,可以是字符串,在这种情况下writeGreekLetter并不真正需要,但这只是一个虚拟示例展示我的主要关注/问题。
【问题讨论】:
-
可能是因为强制转换是显式的。 Enum 可以保护您避免犯愚蠢的错误,但如果您真的想要的话,仍然可以让您绕过它。可能有一个合法的用例。
-
@Carcigenicate 你能想到什么吗?
-
我实际上并不知道 D,但在某些情况下,您可能想计算某个 int 值,然后将其转换为对应的 Enum 值。然后,枚举值将取决于计算中的任何内容。
-
@Carcigenicate 在这种情况下,在
int值上使用一个开关(或者如果,无论如何),并根据该值选择正确的enum。我想说的是:还有更安全的选择!