相比之下,D lang enum型安全

时间:2014-11-20 17:47:53

标签: enums d

这种情况很容易出错:

enum A{x=0};
enum B{y=0};

if (A.x == B.y) {
    writeln("Indeed.");
}

比较不同枚举的枚举...错误地发生在我身上。

如何使这些枚举类型安全?即让dmd至少警告我,我要比较两个不同的枚举?

我知道这两个值都被提升为' int'在比较之前。

有没有办法不创建新类型来帮助我?

编辑:与此问题相关的官方DMD错误报告:https://issues.dlang.org/show_bug.cgi?id=6227(PR:https://github.com/dlang/dmd/pull/6444

3 个答案:

答案 0 :(得分:1)

作为Adam D. Ruppe解决方案的扩展,您可以使用通用比较:

bool compare(T)(T a, T b) if (is(T == enum)) {
    return a == b;
}

至少这种方式你不必为每个枚举类型写一个比较。 它可能不太理想,但我不知道你可以覆盖枚举类型的opEquals,即使你可以,我也不确定我会想要。命名枚举可以作为其基本类型的事实可能是有用的 - 这种不受限制的比较是一个不幸的副作用。

答案 1 :(得分:1)

最后一个解决方案是使用自定义类型和运算符重载。如果您想使用==运算符,则确实如此:

import std.stdio;

struct ExtendedEnumeration(E) if (is(E==enum))
{
    E e;
    alias e this;
    bool opEquals(Rhs)(Rhs rhs){
        static if (is(Rhs == typeof(this)))
            return rhs == e;
        else static if (is(Rhs == E))
            return rhs == e;
        else
            assert(0, "unsupported type for comparison argument");
    }
}

void main(string args[])
{
    enum A{x}
    enum B{y=0}
    ExtendedEnumeration!A a; 
    ExtendedEnumeration!B b;
    writeln(a == b);
}

你有强大的类型安全性。返回

  

core.exception.AssertError@C:... \ temp_0186F968.d(13):比较参数的不支持类型

...确实

如果rhs类型不匹配,你也可以返回false ......但我认为你得到原则。

答案 2 :(得分:0)

只是spitballing但你可以编写一个比较函数并使用它而不是==运算符。对函数参数的枚举类型检查更严格:

enum A{x}
enum B{y=0}

bool compare(A a, A b) {
        return a == b;
}

void main() {
        import std.stdio;
        A a = A.x;
        if (compare(a, B.y)) {
            writeln("Indeed.");
        }
}

test100.d(11):错误:函数test100.compare(A a,A b)不能使用参数类型(A,B)调用

有点sux。