Summary: in this tutorial, you’ll learn about Dart enum to manage a fixed number of constant values.
Introduction to the Dart enum type
Enums or enumerated types are special classes representing a fixed number of constant values.
Declaring an enum
To declare a simple enum, you use the enum
keyword and list some values you want to be enumerated. For example:
enum Status {
pending,
completed,
rejected,
}
Code language: Dart (dart)
By convention, you name the enum using PascalCase
in which you capitalize the first character of each word. Also, you use camelCase
to name enum values.
Using an enum
To access an enum value, you use the enum name, dot operator, and the value. For example:
var initialStatus = Status.pending;
print(initialStatus);
Code language: Dart (dart)
Output:
Status.pending
Code language: Dart (dart)
Each enum value has an index
getter that returns the zero-based position of the value in the enum declaration.
For example, in the Status
enum, the pending has an index of 0, the completed has an index of 1, and the rejected has an index of 2:
enum Status {
pending,
completed,
rejected,
}
void main() {
print(Status.pending.index);
print(Status.completed.index);
print(Status.rejected.index);
}
Code language: Dart (dart)
Output:
0
1
2
Code language: Dart (dart)
To get a list of all enumerated values you use the values constants of the enum like this:
enum Status {
pending,
completed,
rejected,
}
void main() {
List<Status> statuses = Status.values;
for (var status in statuses) {
print(status);
}
}
Code language: Dart (dart)
Output:
Status.pending
Status.completed
Status.rejected
Code language: Dart (dart)
To access the name of an enumerated value, you use the .name
property. For example:
enum Status {
pending,
completed,
rejected,
}
void main() {
List<Status> statuses = Status.values;
for (var status in statuses) {
print(status.name);
}
}
Code language: Dart (dart)
Output:
pending
completed
rejected
Code language: Dart (dart)
Using enum in a switch statement
Enums work very well with the switch
statement. For example:
enum Status {
pending,
completed,
rejected,
}
void main() {
var status = Status.completed;
switch (status) {
case Status.pending:
print('The request is pending');
break;
case Status.completed:
print('The request completed successfully.');
break;
case Status.rejected:
print('The request faield.');
break;
}
}
Code language: Dart (dart)
Notice that if you don’t handle all of the enumerated values, you’ll get a warning. For example:
enum Status {
pending,
completed,
rejected,
}
void main() {
var status = Status.completed;
switch (status) {
case Status.completed:
print('The request completed successfully.');
break;
case Status.rejected:
print('The request faield.');
break;
}
}
Code language: Dart (dart)
Warning:
Missing case clause for 'pending'.
Try adding a case clause for the missing constant, or adding a default
Code language: Dart (dart)
Enum class
All enums automatically extend the Enum
class. Also, you cannot subclass, implement or mix in, or create a new instance of an enum. For example:
enum Status { pending, completed, rejected }
void main() {
var status = Status.completed;
print(status is Enum); // true
}
Code language: Dart (dart)
Enhanced enums
Suppose that you have an enum called OrderStatus
:
enum OrderStatus {
open,
confirmed,
completed,
cancelled,
}
Code language: Dart (dart)
and you want to compare an instance of the OrderStatus
with others like this:
var status = OrderStatus.open;
if (status < OrderStatus.completed) {
//...
}
Code language: Dart (dart)
You’ll get an error:
The operator '<' isn't defined for the type 'OrderStatus'.
Code language: Dart (dart)
To resolve this, you need to use enhanced enums. Like classes, you can define fields, methods, and const constructors with the following rules:
- Instance variables must be final. They cannot have the name
values
because it’ll cause a conflict with the autogeneratedvalues
getter. - Generative constructors must be constant.
- Factory constructors can only return one of the fixed, known enum instances.
- Cannot override
index
,hashCode
, the equality operator==
. - Declare all instances at the beginning of the enum. An enum must have at least one instance.
Note that Dart has supported enhanced enums since version 2.17.
For example:
enum OrderStatus {
open(10),
confirmed(20),
completed(30),
cancelled(40);
final int progress;
const OrderStatus(this.progress);
bool operator <(OrderStatus status) => progress < status.progress;
bool operator >(OrderStatus status) => progress > status.progress;
}
void main() {
var status = OrderStatus.open;
if (status < OrderStatus.completed) {
print('The order has not completed');
}
}
Code language: Dart (dart)
How it works.
First, define the progress
as a final instance variable. By rule, it must be final
:
final int progress;
Code language: Dart (dart)
Next, initialize the progress instance variable in the const
constructor:
const OrderStatus(this.progress);
Code language: Dart (dart)
Then, declare constant values and initialize them with different progress values:
open(10),
confirmed(20),
completed(30),
cancelled(40);
Code language: Dart (dart)
After that, override the less than and greater than operators. In these methods, we compare the progress
of one enum with another:
bool operator <(OrderStatus status) => progress < status.progress;
bool operator >(OrderStatus status) => progress > status.progress;
Code language: Dart (dart)
Finally, use the less-than operator (<
) to compare values of the OrderStatus
enum:
void main() {
var status = OrderStatus.open;
if (status < OrderStatus.completed) {
print('The order has not completed');
}
}
Code language: Dart (dart)
Summary
- Use
enum
type to manage a fixed number of constants.