Enums model fixed sets like states and themes, and exhaustive switches catch missed cases at compile time.
A simple enum lists values: enum Status { idle, loading, done }. Every enum has values (all values in order), each value has index and name, and Status.values.byName('done') looks one up by name.
Enhanced enums (Dart 2.17+) can carry data and behavior like a class:
enum Planet {
mercury(3.3e23, 2.44e6),
earth(5.97e24, 6.37e6);
const Planet(this.mass, this.radius);
final double mass, radius;
double get gravity => 6.67e-11 * mass / (radius * radius);
}Rules: values come first, followed by a semicolon; the constructor must be const; fields must be final. Enums can implement interfaces, use mixins and have static members and getters. They can't be extended or instantiated outside their declaration.
switch over an enum is exhaustive: if you handle every value, no default is needed, and adding a value later makes the compiler flag each switch that misses it. Avoid a catch-all _ when you want this safety.
Enums are compared by identity, are const, and work well as Map keys. For JSON, store value.name and read back with values.byName (or a custom lookup with a fallback for unknown strings from a server).
Example
enum Plan implements Comparable<Plan> {
free(0, maxProjects: 1),
pro(9, maxProjects: 20),
team(29, maxProjects: 100);
const Plan(this.monthlyUsd, {required this.maxProjects});
final int monthlyUsd;
final int maxProjects;
bool get isPaid => monthlyUsd > 0;
@override
int compareTo(Plan other) => monthlyUsd - other.monthlyUsd;
}
String badge(Plan p) => switch (p) { // exhaustive, no default needed
Plan.free => 'Free',
Plan.pro => 'Pro ★',
Plan.team => 'Team',
};
void main() {
print(Plan.values.where((p) => p.isPaid).map((p) => p.name).toList()); // [pro, team]
print(badge(Plan.values.byName('pro'))); // Pro ★
print(Plan.team.index); // 2
print(Plan.free.compareTo(Plan.team) < 0); // true
}Remember
- Enums can have final fields, a const constructor, methods and interfaces
- Switches over enums are exhaustive without
default - Use
nameandvalues.byNamefor serialization
Watch out for
- Adding
_ =>to every enum switch, which hides newly added values.