【问题标题】:Enumeration Type-Safety in DD中的枚举类型安全
【发布时间】:2013-11-07 13:17:06
【问题描述】:

D 中枚举类型安全的状态和计划是什么?

我期待

import std.stdio: writeln;

void main(string args[]) {
    enum E {x, y, z}
    E e;
    writeln(e);
    e = cast(E)3;
    writeln(e);
}

由于 D 的其他强大的静态类型/范围检查而无法编译,或者至少在运行时给出 RangeException。

令我惊讶的是,它改为打印

cast(E)3

这真的是大多数用例的首选默认行为吗?如果是这样,是否有人编写了一些包装器类型,最好在编译时提供更严格的范围检查?

【问题讨论】:

  • 枚举通常也被用作标志,cast 是一个标志,有些事情可能无法正确传递并返回奇数值

标签: casting enums d enumeration type-safety


【解决方案1】:

cast 表示您将事情掌握在自己手中,并且您可以用它做任何事情 - 有用,就像棘轮怪胎所说的那样,用于组合标志。 (虽然,在这些情况下,我喜欢给每个项目一个准确的类型和明确的值,以确保一切都按照我的意愿去做,所以 enum : ubyte { x = 1, y = 2, z = 4},那种东西)

无论如何,在这样的情况下,有一种方法可以获取运行时异常:使用 std.conv.to:

import std.conv;
import std.stdio;

void main() {
    enum E {x, y, z}
    E e;
    writeln(e);
    e = to!E(2); // gives z, whereas to!E(3) throws an exception
    writeln(e);
}

很酷的事实:to!E(string) 也可以。 to!E("x") == E.x, and to!string(E.x) == "x"。

【讨论】:

  • 稍后快速测试:不,它没有。 :p
  • 实现 to!enum(string) 和反之亦然的方式与关于枚举反射的另一个问题有关:他们检查 allMembers 字符串,因此它是一个不错的白名单。 (说到白名单,我实际上在我的 webapps 中使用了枚举:我的 web.d 可以自动从枚举定义中构建
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2017-01-03
相关资源
最近更新 更多