How can I build an enum with Dart?
DartDart 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);