How to search for an enum by values and why enum items aren't unique

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jul 20 15:01:17 PDT 2016


On Wednesday, July 20, 2016 18:08:14 stunaep via Digitalmars-d-learn wrote:
> On Wednesday, 20 July 2016 at 05:45:21 UTC, Jonathan M Davis
>
> wrote:
> > On Wednesday, July 20, 2016 04:03:23 stunaep via
> >
> > Digitalmars-d-learn wrote:
> >> [...]
> >
> > If you want the list of members in an enum, then use
> > std.traits.EnumMembers and you'll get a compile-time list of
> > them. It can be made into a runtime list by being put into an
> > array literal.
> >
> > [...]
>
> Coming from Java I've learned to love enums that are separate
> objects, that can store multiple values, and that can have
> methods that can be in their scope. Seems to me like there's no
> reason to even use enums in D. What's the point when just making
> a constant would do the same exact thing?

Many languages with enums don't even have the ability to have user-defined
types be enum members, and yet many folks find them to be very useful. So,
the fact that you can declare an enum of structs in D is a huge step up over
many languages just like Java's ability to use classes with enums is a shuge
step over such languages. But regardless of the language, pretty much the
whole point of an enum is to group a set of constants together. So, you can
do things like have

enum DayOfWeek : ubyte { sun = 0,
                         mon,
                         tue,
                         wed,
                         thu,
                         fri,
                         sat
                       }

or

enum AddressFamily : int
{
    unspec = AF_UNSPEC,
    unix = AF_UNIX,
    inet = AF_INET,
    inet6 = AF_INET6,
}

and then code can deal with them as being associated rather than just a
bunch of constants with values that happen to be related. It also makes it
more obvious to programmers that they're related. You
can do stuff like

auto foo(AddressFamily af) {...}

and then foo clearly accepts the values in AddressFamily and not just any
random int. You can do stuff like

final switch(myEnum)
{
    case MyEnum.a: ...
    case MyEnum.b: ...
    case MyEnum.c: ...
}

and then get a compilation error when a new member is added to the enum so
that you catch that it wasn't added to the switch. You can get the list of
them together via EnumMembers. stuff like std.conv.to and writeln use the
names of the enum members, not their values. So, they're far more than just
constants with particular values.

If all you need is a few constants and don't care that they have anything to
do with one another, then you don't need to declare an enum. But if you want
to be able to group them such that they're treated as a group, then enums
are great. The fact that you can then have some which are user-defined types
is a great bonus, but it's far from the core aspect of what makes an enum
and makes them useful. Similarly, while it is frequently the case that you
want the enum members to be unique, it's also sometimes the case that you
_don't_ want them to be unique. In general it's the ability to have a group
of associated constants which is what makes enums so valuable, and whether
something like uniqueness or member functions is important depends on the
particular enum and what you're doing with it.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list