Enumerated types, often called enumerations or enums, are a special kind of class used to represent 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,
}
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);
Output:
Status.pending
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);
}
Output:
0
1
2
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;
}
}
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;
}
}
Warning:
Missing case clause for 'pending'.
Try adding a case clause for the missing constant, or adding a default
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
}
Enhanced enums
Suppose that you have an enum called OrderStatus
:
enum OrderStatus {
open,
confirmed,
completed,
cancelled,
}
and you want to compare an instance of the OrderStatus
with others like this:
var status = OrderStatus.open;
if (status < OrderStatus.completed) {
//...
}
You’ll get an error:
The operator '<' isn't defined for the type 'OrderStatus'.
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');
}
}
How it works.
First, define the progress
as a final instance variable. By rule, it must be final
:
final int progress;
Next, initialize the progress instance variable in the const
constructor:
const OrderStatus(this.progress);
Then, declare constant values and initialize them with different progress values:
open(10),
confirmed(20),
completed(30),
cancelled(40);
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;
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');
}
}
Summary
- Use
enum
type to manage a fixed number of constants.