Enums
By Syncfusion®, Inc. · Last updated
How to make a fixed set of choices with enums, read their name and index, add fields and methods with enhanced enums, and use enums in switch.
What Are Enums?
Enum (enumeration) = a type with a fixed list of named values. Nothing else is allowed.
For example:
- the days of the week:
monday,tuesday...sunday - the school houses:
red,blue,green,yellow - the result of an exam:
pass,fail,absent
Simple lesson: an enum is a closed list of choices, and Dart will not accept anything outside it.
A Real-World Example
Every student belongs to one house.
- If the house is stored as text, someone may type
'Bleu'or'blue 'by mistake. - Then the "Blue House" score board misses that student.
- With an enum, the only choices are
House.red,House.blue,House.greenandHouse.yellow. A typo does not compile.
Click a house to see what an enum value knows about itself:
Every Run box on this page runs on the course's Dart runner in your browser.
An enum value prints as EnumName.value, like House.blue.
What You Will Learn
In this lesson, you will learn:
- What enums are, and how to create them.
- How to use
values,name,indexandbyName(). - Enhanced enums with fields, constructors and methods.
- How to give an enum its own
toString(). - How to compare enums and use them in
switch.
Enum Fundamentals
Creating Enums
enum EnumName { value1, value2, value3 }
- The name uses UpperCamelCase:
House,Day,ExamResult. - The values use lowerCamelCase:
red,monday,notStarted. - An enum goes outside
main(), like a class.
Your first enum
enum House { red, blue, green, yellow }
void main() {
var myHouse = House.blue;
print(myHouse);
print(myHouse == House.blue);
print(myHouse == House.red);
}
Enum Values
- Enum value = one of the fixed choices, like
House.blue. - You always write the enum name first:
House.blue, notblue. - Every enum value is an object (see Classes), made once and shared.
Why Not Just Use Strings?
String or enum?
Simple lesson: an enum turns a set of allowed words into a real type that Dart can check.
Accessing Enum Values
| Member | Gives | For House.green |
|---|---|---|
House.values | a list of all values, in order | [House.red, House.blue, House.green, House.yellow] |
.name | the value's name as a String | 'green' |
.index | its position, starting at 0 | 2 |
House.values.byName('green') | the value with that name | House.green |
values, name, index and byName
enum House { red, blue, green, yellow }
void main() {
print(House.values);
print(House.green.name);
print(House.green.index);
print(House.values.length);
var chosen = House.values.byName('yellow');
print(chosen);
for (var h in House.values) {
print('${h.index}: ${h.name}');
}
}
byName with a Wrong Name
There is no purple house
enum House { red, blue, green, yellow }
void main() {
print(House.values.byName('purple'));
}
The error says there is no enum value with that name. byName is exact, so 'Green' with a capital G also fails.
Simple lesson: values lists every choice, name gives its text, and index gives its position.
Enum Comparisons
Comparing Enum Values
==checks if two values are the same choice.indexlets you compare order: is Tuesday before Friday?
Comparing days
enum Day { monday, tuesday, wednesday, thursday, friday, saturday, sunday }
void main() {
var today = Day.tuesday;
var testDay = Day.friday;
print(today == Day.tuesday);
print(today.index < testDay.index);
print('Days until the test: ${testDay.index - today.index}');
print(today == Day.saturday || today == Day.sunday);
}
Using Enums in switch Statements
Enums and switch are a perfect match (see Conditional Statements):
What happens today?
Exhaustive switch = a switch that covers every value of the enum. Dart checks this for you:
- If you forget a case and have no
default, real Dart reports an error before running. - So when you add a new value to an enum later, Dart shows every switch you must update.
A switch expression works too:
A switch expression on an enum
enum Result { pass, fail, absent }
void main() {
var r = Result.absent;
var message = switch (r) {
Result.pass => 'Well done!',
Result.fail => 'Try again next term.',
Result.absent => 'Please see the class teacher.',
};
print(message);
}
No _ arm is needed, because the three arms cover every Result value.
Do not save index in a file or database to remember a choice.
If someone adds a new value in the middle of the enum later, every index after it changes. Save name instead, and read it back with byName.
Simple lesson: use == to compare enum values, and switch to act on each one.
Enhanced Enums
Enhanced enum = an enum that also has fields, a constructor and methods, like a small class.
Enum Fields and Constructors
Houses with a motto and points
enum House {
red('Courage', 120),
blue('Wisdom', 145),
green('Growth', 98),
yellow('Joy', 110);
final String motto;
final int points;
const House(this.motto, this.points);
}
void main() {
print(House.blue.motto);
print(House.blue.points);
for (var h in House.values) {
print('${h.name}: ${h.motto}, ${h.points} points');
}
}
Rules for enhanced enums:
- Constant constructor: the constructor must be
const. - Read-only fields: every field must be
final. Enum values never change. - Parameterized enum values: each value passes its own arguments:
red('Courage', 120). - The value list ends with
;before the fields.
Enum Methods and Custom Properties
Methods can use the fields, just like in a class:
Methods on an enum
enum Planet {
mercury(3.7),
earth(9.8),
jupiter(24.8);
final double gravity;
const Planet(this.gravity);
double weightOf(double massKg) => massKg * gravity;
bool get isHeavierThanEarth => gravity > 9.8;
}
void main() {
for (var p in Planet.values) {
var w = p.weightOf(40.5).toStringAsFixed(1);
print('${p.name}: $w N, heavier than Earth: ${p.isHeavierThanEarth}');
}
}
isHeavierThanEarth is a getter: a method you read like a field, with no () (see Encapsulation).
Overriding toString()
A friendlier print
enum Subject {
maths('Mathematics'),
sci('Science'),
eng('English');
final String fullName;
const Subject(this.fullName);
@override
String toString() => fullName;
}
void main() {
print(Subject.sci);
print('Favourite: ${Subject.maths}');
print(Subject.eng.name);
}
toString() now prints the full name. name still gives the short value name, eng.
Easy way to remember
- A fixed list of choices: enum.
- Each choice needs extra data: enhanced enum, with
finalfields and aconstconstructor. - Act on each choice: switch, and let Dart check you covered them all.
Simple lesson: an enhanced enum gives every choice its own data and behaviour.
TL;DR
Enum = a fixed list of values:
enum House { red, blue, green }.- Use as
House.red. Each value is a shared object.
- Use as
- Members:
House.values,.name,.index,House.values.byName('red'). Compare with
==, and order withindex.- switch on enums, and Dart checks every value is covered.
- Enhanced enum = values with arguments,
finalfields, aconstconstructor, and methods. toString()can be overridden to print a friendlier text.
Common mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
var h = blue; | Values stand alone | Write House.blue | Undefined name 'blue'. |
| Storing choices as Strings | Text is simpler | An enum stops typos | 'Bleu' silently breaks your code. |
byName('Blue') | Case does not matter | Names are exact | An invalid argument error. |
| A non-final field in an enum | Enum values can change | Every enum field must be final | A compile error. |
A constructor without const | Any constructor works | Enum constructors must be const | A compile error. |
| Forgetting a case in a switch | Missing values are skipped | Dart wants every value covered | An exhaustiveness error. |
Expecting index to start at 1 | The first value is 1 | index starts at 0 | Off-by-one numbers. |
Check Yourself
Exercises
What to Remember
- An enum is a fixed list of choices, used as
EnumName.value. valueslists them,namegives the text, andindexgives the position from 0.- Compare enum values with
==, and use them inswitch, where Dart checks every case. - Enhanced enums add
finalfields, aconstconstructor and methods. - Override
toString()for friendlier output, whilenamestays the same.
Next: Encapsulation. You will learn to hide an object's data and control how it is read and changed.