How can I build an enum with Dart?

Dart

Dart Problem Overview


The Dart language does not have enums (yet??). What is the proper or idiomatic way to construct an enum, at least until a language feature arrives?

Dart Solutions


Solution 1 - Dart

Dart now has support for enums.

The rest of this answer is for Dart <= 1.8. If using > 1.8, use Dart's formal support for enums (explained in another answer).

It's true, the Dart language does not (yet?) have enums. There is an open issue for it.

In the meantime, here is an idiomatic Dart snippet to create your own enum.

class Enum {
  final _value;
  const Enum._internal(this._value);
  toString() => 'Enum.$_value';

  static const FOO = const Enum._internal('FOO');
  static const BAR = const Enum._internal('BAR');
  static const BAZ = const Enum._internal('BAZ');
}

Using const constructors means you can use this enum in a switch. Here's an example:

class Fruits {
  final _value;
  const Fruits._internal(this._value);
  toString() => 'Enum.$_value';

  static const APPLE = const Fruits._internal('APPLE');
  static const PEAR = const Fruits._internal('PEAR');
  static const BANANA = const Fruits._internal('BANANA');
}

void main() {
  var yummy = Fruits.BANANA;
  
  switch (yummy) {
    case Fruits.APPLE:
      print('an apple a day');
      break;
    case Fruits.PEAR:
      print('genus Pyrus in the family Rosaceae');
      break;
    case Fruits.BANANA:
      print('open from the bottom, it is easier');
      break;
  }
}

Solution 2 - Dart

With r41815 Dart got native Enum support see http://dartbug.com/21416 and can be used like

enum Status {
  none,
  running,
  stopped,
  paused
}

void main() {
  print(Status.values);
  Status.values.forEach((v) => print('value: $v, index: ${v.index}'));
  print('running: ${Status.running}, ${Status.running.index}');
  print('running index: ${Status.values[1]}');
}

> [Status.none, Status.running, Status.stopped, Status.paused]
> value: Status.none, index: 0
> value: Status.running, index: 1
> value: Status.stopped, index: 2
> value: Status.paused, index: 3
> running: Status.running, 1
> running index: Status.running

A limitation is that it is not possibly to set custom values for an enum item, they are automatically numbered.

More details at in this draft https://www.dartlang.org/docs/spec/EnumsTC52draft.pdf

Solution 3 - Dart

I use a little bit simpler version of the Enum class in Dart Web Toolkit:

/**
 * Emulation of Java Enum class.
 *
 * Example:
 *
 * class Meter<int> extends Enum<int> {
 *
 *  const Meter(int val) : super (val);
 *
 *  static const Meter HIGH = const Meter(100);
 *  static const Meter MIDDLE = const Meter(50);
 *  static const Meter LOW = const Meter(10);
 * }
 *
 * and usage:
 *
 * assert (Meter.HIGH, 100);
 * assert (Meter.HIGH is Meter);
 */
abstract class Enum<T> {

  final T _value;

  const Enum(this._value);

  T get value => _value;
}

Solution 4 - Dart

I like top-level constants for my enums. You can use imports to fix any collisions. This makes using the enums much less verbose.

i.e.

if (m == high) {}

instead of:

if (m == Meter.high) {}

Enum definition:

class Meter<int> extends Enum<int> {
   const Meter(int val) : super (val);
}

const Meter high = const Meter(100);
const Meter middle = const Meter(50);
const Meter low = const Meter(10);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSeth LaddView Question on Stackoverflow
Solution 1 - DartSeth LaddView Answer on Stackoverflow
Solution 2 - DartGünter ZöchbauerView Answer on Stackoverflow
Solution 3 - DartaksergView Answer on Stackoverflow
Solution 4 - DartGreg LoweView Answer on Stackoverflow