
Flutter 3: What are enums and what is new about it
Let’s continue our Flutter 3 series. Enums have got a new power in Flutter 3/Dart 2.17; in this article, I will talk about what enum is and its new feature in Flutter 3.
What’s Enum
Enum is the short form of “Enumerated type”, a set of named constants where all possible values are declared. Enum is not a unique feature of the Dart language but exists in most modern languages.
For example, if I’m going to develop a programmable interface for a smart lightbulb, I may do this:
const int LIGHT_BULB_STATUS_ON = 1;
const int LIGHT_BULB_STATUS_OFF = 0;Then I will define a function to set the status of the lightbulb to on or off:
void setStatus(int status) {
// ...
}// Usage:
setStatus(LIGHT_BULB_STATUS_ON);This seems fine but one day a junior employee is adding new features to the codebase, and he sees that the setStatus function takes an integer parameter, then he somehow passed -1 to it, causing a runtime exception:
setStatus(-1);It is not a good practice that he didn’t read through the codebase before doing any modification, but if the codebase is very large, who wants to read it? Is there a way to let us find the problem even in the static analysis, without running the code? Enums to the rescue!
First, we define an enum class:
enum LightBulbStatus {
on,
off,
}Then the setStatus function becomes:
void setStatus(LightBulbStatus status) {
// ...
}// Usage:
setStatus(LightBulbStatus.on);Now the function takes a value of the enum LightBulbStatus, which is on or off only. This has two advantages:
- It restricts the parameter to the values declared in the enum, passing other values to it would give an error, and the error can be found by editor plugins.
- It prevents others from passing direct values to the function, e.g.
setStatus(0), which ensures the readability.
Therefore, you should always use enums when possible.
A week later, the hardware department came and said, the lower level of the interface(written in C) takes 1 or 0 to indicate on or off, and we need to pass an integer to it. What should I do?
Some of you may do this:
void setStatus(LightBulbStatus status) async {
if (status == LightBulbStatus.on) {
await channel.invokeMethod('setStatus', 1);
} else {
await channel.invokeMethod('setStatus', 0);
}
}This seems fine but if later we want to add an extra status standby(2), we need to update both the LightBulbStatus class and the setStatus method again, which is time-consuming and error-prone.
Enums in Dart 2.12
Unfortunately in Flutter 2/Dart 2.12, enums can’t carry any values, so we had to use a class to pretend an enum class:
class LightBulbStatus {
final int value;
// A private constructor to prevent instantiation from outside
const LightBulbStatus._(this.value);
// declare as constants so that we can use the `==` operator
// to compare them or use them in `switch` cases
static const on = LightBulbStatus._(1);
static const off = LightBulbStatus._(0);
// add a `values` getter so that we can use `LightBulbStatus.values` to
// get all possible values just like an enum class
static List<LightBulbStatus> get values => [on, off];
}Luckily the usage didn’t change so much:
void setStatus(LightBulbStatus status) async {
// the `value` of the status, which is an integer,
// is passed to the platform channel
await channel.invokeMethod('setStatus', status.value);
}// Usage:
setStatus(LightBulbStatus.on);This is just a workaround, note that besides the values getter, we need to implement ourselves if we want to use the .index and .name property just like normal enums.
Enum’s new power
In Flutter 3/Dart 2.17, there’s a new feature called “Enhanced enums”, which lets us add fields/methods to enums, so the LightBuildStatus class can be simplified to:
// enhanced enum is more like a constant class
enum LightBulbStatus {
on(1),
off(0);
// can add more properties or getters/methods if needed
final int value;
// can use named parameters if you want
const LightBulbStatus(this.value);
}Later if we want to add another status standby, just add one line to the LightBuildStatus class and it’s done:
// enhanced enum is more like a constant class
enum LightBulbStatus {
on(1),
standby(2),
off(0);
// can add more properties or getters/methods if needed
final int value;
// can use named parameters if you want
const LightBulbStatus(this.value);
}By using this feature, boilerplates are reduced and hence human mistakes. The code is more elegant, and we don’t have to update the setStatus function again, isn’t it amazing?
Conclusion
In this article, we have covered what enums are and why should we use them. We have also talked about the usage of enhanced enums, which is a new feature of Flutter 3/Dart 2.17. Please generously hold the clap button if this article helped you; follow my profile if you want to see more news/tricks of Flutter. See you in the next one, cheers~





