Home > Mobile >  What is 'extension' in dart?
What is 'extension' in dart?

Time:09-24

Explain what's going on here in the following snippet.

enum WeatherStatus { initial, loading, success, failure }

extension WeatherStatusX on WeatherStatus {
  bool get isInitial => this == WeatherStatus.initial;
  bool get isLoading => this == WeatherStatus.loading;
  bool get isSuccess => this == WeatherStatus.success;
  bool get isFailure => this == WeatherStatus.failure;
}

CodePudding user response:

An extension declaration associates members to a type.

Normally, in Dart, a method is either associated with a class or interface (instance methods) or with a static (class/mixin/library/etc) namespace (static methods).

An extension declaration instead associates methods directly with a type, which doesn't have to be an interface type (but can be).

When you try to call a method on something typed as WeatherStatus, say

var status = WeatherStatus.initial;
print(status.isInitial);

the compiler first checks whether the WeatherStatus interface has an isInitial instance member. Since it doesn't, it then goes on to check if there are any extension methods associated with the WeatherStatus type.

There is (because the WeatherStatusX extension is in scope), and then it instead calls WeatherStatusX(status).isInitial which invokes that method with this bound to the status object.

It's a way to add members on a type from the side, without needing to add them to the class itself (which you can't if it's not your class). The trade-off is that extension methods are not virtual. You can't add an override in a subclass, and get it called even if the caller only know the object at the superclass type, like you can for classes.

In reality, extension methods are most like static helper functions. You could write:

bool isInitial(WeatherStatus self) => self == WeatherStatus.initial;

and call it as isInitial(status). The extension declaration allows you to pretend that a static helper function is more like a special instance method, because you call it as status.isInitial, but it really isn't an instance method. It just looks like one.

In this particular case, I'd recommend using the newest version of the Dart SDK so you can use the new enhanced enum feature:

enum WeatherStatus {
  initial, loading, success, failure;
  bool get isInitial => this == initial;
  bool get isLoading => this == loading;
  bool get isSuccess => this == success;
  bool get isFailure => this == failure;
}

This makes the isInitial, etc., getters actual instance members on the enum class. (Still can't override them, since enums can't have subclasses, but you don't need to worry about whether extension WeatherStatusX is imported before you use them.)

  •  Tags:  
  • dart
  • Related