okaryo.log

Creating Factory Constructors for enums with Dart 2.17's enhanced enums | okaryo.log

Creating Factory Constructors for enums with Dart 2.17's enhanced enums

    #Dart

Introduction

Recently, I’ve been developing a Flutter application personally, and I found myself in a situation where I wanted to generate an enum from a string.

Previously, I defined methods for enums using Extensions. However, remembering that enums were enhanced in Dart 2.17, I researched and found that it was possible to achieve this without Extensions. I wanted to summarize this for personal reference.

Enhanced enums

What are enhanced enums?

First, let’s briefly touch on enhanced enums. Borrowing code from the official page, enhanced enums allow you to define instance variables, methods, and constructors within the enum itself, as shown below:

enum Vehicle implements Comparable<Vehicle> {
  car(tires: 4, passengers: 5, carbonPerKilometer: 400),
  bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
  bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

  const Vehicle({
    required this.tires,
    required this.passengers,
    required this.carbonPerKilometer,
  });

  final int tires;
  final int passengers;
  final int carbonPerKilometer;

  int get carbonFootprint => (carbonPerKilometer / passengers).round();

  @override
  int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}

However, there are some constraints:

  • Instance variables must be final.
  • Generative constructors must be const.
  • Factory constructors must return a defined enum (cannot return null).
  • Extending other classes is not allowed.
  • Overriding index, hashCode, or == is not possible.
  • Members named values cannot be defined (to avoid conflict with auto-generated members by enum).
  • At least one instance must be defined at the beginning of the declaration.

Factory Constructor

While the official page doesn’t provide an example, Factory constructors can also be defined:

enum Color {
  red,
  blue,
  none; // Note the semicolon!

  factory Color.from(String value) {
    switch (value) {
      case 'red':
        return Color.red;
      case 'blue':
        return Color.blue;
      default:
        return Color.none;
    }
  }
}

Color.from('red') // Returns Color.red

Due to the constraints of enhanced enums, it’s not possible to return null. Hence, it’s crucial to provide some sort of handling (like throwing an error or returning a dedicated enum) for unexpected arguments.

Conclusion

Enums have become much more convenient with enhanced enums. I look forward to using them more frequently and updating my existing code accordingly.


Related Posts
Related Posts
Promotion

This site uses Google Analytics.