Enums, Unions and Sum Types

14.1 Enums

Enums are strongly typed. final switch guarantees exhaustive handling.

enum is also used for manifest constants: enum size = 1024;, enum table = generateTable(); (CTFE).

enum Color { red, green, blue }
enum Status : int { ok = 200, notFound = 404 }
enum Planet : string { earth = "Earth", mars = "Mars" }
enum : int { A = 1, B, C }               // anonymous enum (constants)

auto c = Color.green;
writeln(c, " ", cast(int) c, " ", Color.max, " ", Color.min);
import std.traits : EnumMembers;
foreach (m; EnumMembers!Color) write(m, " ");
import std.conv : to;
auto parsed = "blue".to!Color;

14.2 Unions

union IntOrFloat { int i; float f; }
IntOrFloat u;
u.f = 1.0f;
writeln(u.i);      // reinterpret (unsafe in @safe code if pointers are involved)

14.3 Sum Types (std.sumtype)

std.variant (Variant, Algebraic (deprecated)) for dynamic typing. Nullable!T (std.typecons) for optional values.

import std.sumtype;

struct Circle { double r; }
struct Rect { double w, h; }
alias Shape = SumType!(Circle, Rect);

double area(Shape s)
{
    return s.match!(
        (Circle c) => 3.14159 * c.r * c.r,
        (Rect r) => r.w * r.h
    );     // compile error if a case isn't handled
}

Shape s = Circle(2);
writeln(area(s));
s = Rect(3, 4);