在D中使用简单的枚举器

时间:2018-02-11 15:39:59

标签: enums d

说我有以下枚举:

struct Test {
    string value;
}

Test new_test(string value) {
    Test t;
    t.value = value;
    return t;
}

enum Foo : Test {
    A = new_test("a"),
    B = new_test("b"),
    c = new_test("c"),
}

我对一些事感到困惑。如何将其传递给函数?

void do_something(Foo f) {

}
do_something(Foo.A);

// or

void do_something(Test t) {

}
do_something(Foo.A);

最后,有什么方法可以得到枚举的数值 例如

A -> 0
B -> 1
C -> 2

简单的事情:

Foo.A.id ???

2 个答案:

答案 0 :(得分:2)

写作时

 enum Foo {
     A = new_test("a"),
     B = new_test("b"),
     C = new_test("c"),
 }

您基本上是在创建一组命名的值。它们没有数值,你的想法 - 它们只是常规结构。如果您需要知道集合中值的索引(这样getIndex(Foo.C)将返回2),您可以使用以下代码:

// Gets the index of an enum value in the enum it's part of.
int getIndex(T)(T value) if (is(T == enum)) {
    // Iterate over all the members of the enum, and return the index if it's a match.
    static foreach (i, member; __traits(allMembers, T)) {
        if (value == __traits(getMember, T, member))
            return i;
    }
    return -1;
}

至于传递它,无论哪种方式都有效,你可能已经注意到了。再一次,枚举没有什么神奇之处。它们不是伪装成Test的数字,并且可以在各个方面像Test一样使用。

答案 1 :(得分:1)

我不知道你为什么在这里定义FooTest,你可以只有一个匿名的枚举:

enum Foo {
  a,
  b,
  c, 
}

或将其定义为字符串:

enum Foo {
  A="a",
  B="b",
  C="c", 
}

无论如何,这取决于你的功能设计,如果该功能只应该收到Foo那么你应该传递FooTest相同,如果你的功能你写作应该适用于所有Test个对象,不仅这3个预定义的Test然后传递Test将是您的选择,但是,如果您希望该函数仅适用于枚举您定义然后使用Foo,你明白了。

关于id,我们假设您可以Test包含另一个名为id的字段,并使用数字对其进行初始化,现在您可以将该字段用作标识符:

struct Test {
    string value;
    int id;
}

Test new_test(string value, int id) {
    Test t;
    t.value = value;
    t.id = id;
    return t;
}

enum Foo : Test {
    A = new_test("a", 1),
    B = new_test("b", 2),
    c = new_test("c", 3),
}

现在,如果你想获得一个Foo的索引,你可以使用特征:

auto i = [__traits(allMembers, Foo)].countUntil(Foo.B.to!string);