enum - D Programming Language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Discord (community-run)
  - Forums
  - IRC
  - Wiki
  - Issues
  - Contributing
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# enum

`enum` is the feature that enables defining named constant values.

##### Effects of magic constants on code quality

The following code appeared in the exercise solutions of the Integers and Arithmetic Operations chapter:

            if (operation == 1) {
                result = first + second;

            } else if (operation == 2) {
                result = first - second;

            } else if (operation == 3) {
                result = first * second;

            } else if (operation == 4) {
                result = first / second;
            }

The integer literals `1`, `2`, `3`, and `4` in that piece of code are called magic constants. It is not easy to determine what each of those literals means in the program. One must examine the code in each scope to determine that `1` means addition, `2` means subtraction, etc. This task is relatively easy for the code above because all of the scopes contain just a single line. It would be considerably more difficult to decipher the meanings of magic constants in most other programs.

Magic constants must be avoided because they impair two important qualities of source code: readability and maintainability.

`enum` enables giving names to such constants and, as a consequence, making the code more readable and maintainable. Each condition would be readily understandable if the following `enum` constants were used:

            if (operation == Operation.add) {
                result = first + second;

            } else if (operation == Operation.subtract) {
                result = first - second;

            } else if (operation == Operation.multiply) {
                result = first * second;

            } else if (operation == Operation.divide) {
                result = first / second;
            }

The `enum` type `Operation` above that obviates the need for magic constants `1`, `2`, `3`, and `4` can be defined like this:

        enum Operation { add = 1, subtract, multiply, divide }

##### The `enum` syntax

The common definition of an `enum` is the following:

        enum TypeName { ValueName_1, ValueName_2, /* etc. */ }

Sometimes it is necessary to specify the actual type (the base type) of the values as well:

        enum TypeName : base_type { ValueName_1, ValueName_2, /* etc. */ }

We will see how this is used in the next section.

TypeName defines what the constants collectively mean. All of the member constants of an `enum` type are listed within curly brackets. Here are some examples:

        enum HeadsOrTails { heads, tails }
        enum Suit { spades, hearts, diamonds, clubs }
        enum Fare { regular, child, student, senior }

Each set of constants becomes part of a separate type. For example, `heads` and `tails` become members of the type `HeadsOrTails`. The new type can be used like other fundamental types when defining variables:

        HeadsOrTails result;           // default initialized
        auto ht = HeadsOrTails.heads;  // inferred type

As has been seen in the pieces of code above, the members of `enum` types are always specified by the name of their `enum` type:

        if (result == HeadsOrTails.heads) {
            // ...
        }

##### Actual values and base types

The member constants of `enum` types are by default implemented as `int` values. In other words, although on the surface they appear as just names such as `heads` and `tails`, they also have numerical values. (Note: It is possible to choose a type other than `int` when needed.).

Unless explicitly specified by the programmer, the numerical values of `enum` members start at `0` and are incremented by one for each member. For example, the two members of the `HeadsOrTails` `enum` have the numerical values 0 and 1:

        writeln("heads is 0: ", (HeadsOrTails.heads == 0));
        writeln("tails is 1: ", (HeadsOrTails.tails == 1));

The output:

    heads is 0: true
    tails is 1: true

It is possible to manually (re)set the values at any point in the `enum`. That was the case when we specified the value of `Operation.add` as 1 above. The following example manually sets a new count twice:

        enum Test { a, b, c, ç = 100, d, e, f = 222, g, ğ }
        writefln("%d %d %d", Test.b, Test.ç, Test.ğ);

The output:

    1 100 224

If `int` is not suitable as the base type of the `enum` values, the base type can be specified explicitly after the name of the `enum`:

        enum NaturalConstant : double { pi = 3.14, e = 2.72 }
        enum TemperatureUnit : string { C = "Celsius", F = "Fahrenheit" }

##### `enum` values that are not of an `enum` type

We have discussed that it is important to avoid magic constants and instead to take advantage of the `enum` feature.

However, sometimes it may not be natural to come up with `enum` type names just to use named constants. Let's assume that a named constant is needed to represent the number of seconds per day. It should not be necessary to also define an `enum` type to contain this constant value. All that is needed is a constant value that can be referred to by its name. In such cases, the type name of the `enum` and the curly brackets are omitted:

        enum secondsPerDay = 60 * 60 * 24;

The type of the constant can be specified explicitly, which would be required if the type cannot be inferred from the right hand side:

        enum int secondsPerDay = 60 * 60 * 24;

Since there is no `enum` type to refer to, such named constants can be used in code simply by their names:

        totalSeconds = totalDays * secondsPerDay;

`enum` can be used for defining named constants of other types as well. For example, the type of the following constant would be `string`:

        enum fileName = "list.txt";

Such constants are rvalues and they are called manifest constants.

It is possible to create manifest constants of arrays and associative arrays as well. However, as we will see later in the Immutability chapter, `enum` arrays and associative arrays may have hidden costs.

##### Properties

The `.min` and `.max` properties are the minimum and maximum values of an `enum` type. When the values of the `enum` type are consecutive, they can be iterated over in a `for` loop within these limits:

        enum Suit { spades, hearts, diamonds, clubs }

        for (auto suit = Suit.min; suit <= Suit.max; ++suit) {
            writefln("%s: %d", suit, suit);
        }

Format specifiers `"%s"` and `"%d"` produce different outputs:

    spades: 0
    hearts: 1
    diamonds: 2
    clubs: 3

Note that a `foreach` loop over that range would leave the `.max` value out of the iteration:

        foreach (suit; Suit.min .. Suit.max) {
            writefln("%s: %d", suit, suit);
        }

The output:

    spades: 0
    hearts: 1
    diamonds: 2
                   ← clubs is missing

For that reason, a correct way of iterating over all values of an `enum` is using the `EnumMembers` template from the `std.traits` module:

    import std.traits;
    // ...
        foreach (suit; EnumMembers!Suit) {
            writefln("%s: %d", suit, suit);
        }

Note: The `!` character above is for template instantiations, which will be covered in a later chapter.

    spades: 0
    hearts: 1
    diamonds: 2
    clubs: 3       ← clubs is present

##### Converting from the base type

As we saw in the formatted outputs above, an `enum` value can automatically be converted to its base type (e.g. to `int`). The reverse conversion is not automatic:

        Suit suit = 1;       // ← derleme HATASI

One reason for this is to avoid ending up with invalid `enum` values:

        suit = 100;          // ← would be an invalid enum value

The values that are known to correspond to valid `enum` values of a particular `enum` type can still be converted to that type by an explicit type cast:

        suit = cast(Suit)1;  // now hearts

It would be the programmer's responsibility to ensure the validity of the values when an explicit cast is used. We will see type casting in a later chapter.

##### Problem

Modify the calculator program from the exercises of the Integers and Arithmetic Operations chapter to have the user select the arithmetic operation from a menu.

This program should be different from the previous one in at least the following areas:

- Use `enum` values, not magic constants.
- Use `double` instead of `int`.
- Use a `switch` statement instead of an "if, else if, else" chain.

... çözüm

Copyright © 1999-2026 by the D Language Foundation | Page generated by Ddoc on Mon Aug 17 18:57:13 2026