flutter
/

Dart Enums – Complete Guide with Examples

Last Sync: Today

On this page

11
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

Dart Enums – Complete Guide with Examples

What are Enums?

Enums (short for enumerations) are a way to define a set of named constants. They are useful when you have a fixed set of related values, like days of the week, status codes, or user roles. In Dart, enums are more powerful than in many other languages – since Dart 2.17, you can create enhanced enums that have fields, constructors, methods, and can even implement interfaces.

Simple Enum

The simplest enum is defined using the enum keyword followed by the name and a list of constant values.

DARTRead-only
1
enum Status {
  pending,
  processing,
  completed,
  failed
}

void main() {
  Status status = Status.pending;
  print(status); // Status.pending
}

Enum Properties

Every enum has a few built‑in properties:

    • .name – returns the string name of the enum value (e.g., 'pending').
    • .index – returns the zero‑based index of the enum value.
    • .values – returns a list of all enum values (of type List<Enum>).
DARTRead-only
1
enum Status {
  pending,
  processing,
  completed,
  failed
}

void main() {
  Status s = Status.pending;
  print(s.name);   // pending
  print(s.index);  // 0

  for (var status in Status.values) {
    print(status.name);
  }
}

Enums in Switch Statements

One of the most common uses of enums is in switch statements. Since enums have a finite set of values, you can easily handle all cases without a default (but it's good practice to include default or handle all cases).

DARTRead-only
1
void printStatusMessage(Status status) {
  switch (status) {
    case Status.pending:
      print('Your request is pending.');
      break;
    case Status.processing:
      print('We are processing your request.');
      break;
    case Status.completed:
      print('Request completed successfully.');
      break;
    case Status.failed:
      print('Request failed.');
      break;
  }
}

void main() {
  printStatusMessage(Status.completed);
}

Enhanced Enums (Dart 2.17+)

With Dart 2.17, enums can have constructors, fields, and methods. This makes them much more powerful and allows you to attach additional data to each enum value.

DARTRead-only
1
enum Status {
  pending('⏳', 'Waiting'),
  processing('🔄', 'In progress'),
  completed('✅', 'Done'),
  failed('❌', 'Error');

  final String icon;
  final String message;

  const Status(this.icon, this.message);

  String get display => '$icon $message';
}

void main() {
  Status status = Status.pending;
  print(status.display); // ⏳ Waiting
  print(status.message); // Waiting
}

Enhanced Enum with Methods

You can add methods to enums, including getters, setters (though not recommended), and even implement interfaces.

DARTRead-only
1
enum Grade {
  A(90, 'Excellent'),
  B(80, 'Good'),
  C(70, 'Satisfactory'),
  D(60, 'Pass'),
  F(0, 'Fail');

  final int minScore;
  final String description;

  const Grade(this.minScore, this.description);

  bool isPassing() => this != F;

  @override
  String toString() => '$name ($description)';
}

void main() {
  Grade grade = Grade.B;
  print(grade);                // B (Good)
  print(grade.isPassing());    // true
  print(grade.minScore);       // 80
}

Enums Implementing Interfaces

Enhanced enums can implement interfaces, allowing them to behave polymorphically.

DARTRead-only
1
abstract class CanDescribe {
  String describe();
}

enum Vehicle implements CanDescribe {
  car('🚗', 4),
  motorcycle('🏍️', 2),
  bicycle('🚲', 2);

  final String icon;
  final int wheels;

  const Vehicle(this.icon, this.wheels);

  @override
  String describe() => '$icon A vehicle with $wheels wheels.';
}

void main() {
  Vehicle v = Vehicle.car;
  print(v.describe()); // 🚗 A vehicle with 4 wheels.
}

Common Mistakes

    • Using const on enum instances: Enhanced enums require const constructors. Always mark the constructor as const.
    • Forgetting to handle all cases in a switch: With simple enums, it's okay to use a default; with enhanced enums, you can still use a default, but it's better to cover all cases.
    • Over‑engineering simple enums: If you just need a fixed set of names, a simple enum is enough. Use enhanced enums only when you need extra data or behaviour.

Best Practices

    • Use enums when you have a fixed, known set of values.
    • Prefer enums over string constants for type safety.
    • In switch statements, handle all enum values to avoid missing cases (the analyzer can help with exhaustiveness checking).
    • For enhanced enums, keep fields final and constructors const to maintain immutability.

Complete Example

DARTRead-only
1
enum HttpStatus {
  ok(200, 'OK'),
  created(201, 'Created'),
  badRequest(400, 'Bad Request'),
  unauthorized(401, 'Unauthorized'),
  notFound(404, 'Not Found'),
  serverError(500, 'Internal Server Error');

  final int code;
  final String message;

  const HttpStatus(this.code, this.message);

  bool isSuccess() => code >= 200 && code < 300;
  bool isClientError() => code >= 400 && code < 500;
  bool isServerError() => code >= 500;

  @override
  String toString() => '$code $message';
}

void main() {
  var status = HttpStatus.notFound;
  print(status);                 // 404 Not Found
  print(status.isSuccess());     // false
  print(status.isClientError()); // true

  for (var s in HttpStatus.values) {
    print(s);
  }
}

Key Takeaways

    • Enums define a fixed set of named constants.
    • Simple enums are defined with enum Name { value1, value2 }.
    • Use .name, .index, and .values to get information about enum values.
    • Enhanced enums (Dart 2.17+) can have fields, constructors, methods, and implement interfaces.
    • Enhanced enums must use const constructors and all fields must be final.
    • Enums are perfect for status codes, roles, categories, and other fixed sets.

Try it yourself

enum Weather {
  sunny('☀️', 'Clear skies'),
  cloudy('☁️', 'Overcast'),
  rainy('🌧️', 'Rain showers'),
  snowy('❄️', 'Snowfall');

  final String icon;
  final String description;

  const Weather(this.icon, this.description);

  @override
  String toString() => '$icon $description';
}

void main() {
  Weather today = Weather.sunny;
  print(today); // ☀️ Clear skies

  for (var w in Weather.values) {
    print(w);
  }
}

Test Your Knowledge

Q1
of 4

How do you get the string name of an enum value?

A
.string
B
.name
C
.toString()
D
.value
Q2
of 4

What keyword is required for enhanced enum constructors?

A
new
B
final
C
const
D
static
Q3
of 4

Which of the following is NOT a property of all enums?

A
.values
B
.index
C
.name
D
.toString()
Q4
of 4

In a switch statement, what does handling all enum values without a default achieve?

A
Better performance
B
Exhaustiveness checking (the analyzer warns if you miss a case)
C
Less code
D
Faster execution

Frequently Asked Questions

Can an enum have multiple constructors?

Yes, an enhanced enum can have multiple named constructors, as long as they call the main constructor (via this). For example: enum Color { red(0xFF0000), green(0x00FF00), blue(0x0000FF); const Color(this.hex); Color.fromHex(String hex) : this(int.parse(hex, radix: 16)); }

Are enums comparable?

Yes, enums are comparable. You can use == and hashCode are defined based on the enum value identity. For sorting, you can use .index.

Can I add methods to a simple enum?

No, simple enums (without fields) cannot have methods. To add methods, you must use an enhanced enum (with a constructor and fields).

How do I get the string name of an enum value?

Use the .name property: MyEnum.someValue.name returns 'someValue'. This is available for all enums.

Can I create an enum with integer values like in C#?

Yes, in Dart you can associate integer values with each enum instance using fields. The index is always available, but you can define a custom field if you need a different numeric value.

What is the difference between an enum and a class with static constants?

Enums give you a distinct type, can be used in switch statements with exhaustiveness checking, and provide a fixed set of instances. A class with static constants doesn't give you the same type safety and can't be easily enumerated.

Previous

dart extension types

Next

dart json

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.