Я просматривал журналы изменений Dart SDK и заметил это в примечаниях к выпуску Dart SDK v2.14:
Я не смог найти никакой документации по этому поводу! Где я могу это использовать? Я пытался это реализовать, но не получилось!
Я просматривал журналы изменений Dart SDK и заметил это в примечаниях к выпуску Dart SDK v2.14:
Я не смог найти никакой документации по этому поводу! Где я могу это использовать? Я пытался это реализовать, но не получилось!
Сценарии использования суперинтерфейса Enum
для всех объявленных типов enum
, которые привели к добавлению интерфейса, в основном были запросом на возможность абстрагироваться от перечислений.
Одним из наиболее частых запросов было извлечение имени из перечисления. Пример:
enum FooBar {
foo, bar;
}
Люди спрашивали, как получить строку "foo"
из значения FooBar.foo
.
Имя является доступным в toString
, который возвращает строку "FooBar.foo"
, но недоступен иным образом.
Общим подходом было сделать
String enumName(dynamic value) {
var string = enumValue.toString();
return string.substring(string.indexOf('.') + 1);
}
Вы не могли ограничить value
только значениями перечисления, потому что не было способа распознать значения перечисления в системе типов. Теперь это можно записать как
String enumName(Enum value) { ... }
вместо этого или как расширение:
extension EnumName on Enum {
String get name => ....;
}
(Преимущество расширения состоит в том, что оно не мешает вам иметь перечисление с членом name
, скажем, enum PostalReceiver { name, address, zip, country; }
, что было бы членом экземпляра).
Другим примером может быть копия Java EnumSet
:
class EnumSet<T extends Enum> {
int _bits = 0;
final List<T> _values;
EnumSet(List<T> values) : _values = values {
if (values.length > 32) throw UnsupportedError("Too big");
}
void add(T value) {
_bits |= 1 << value.index;
}
void remove(T value) {
_bits &= ~(1 << value.index);
}
bool contains(T value) => _bits & (1 << value.index) != 0;
}
Теперь это может быть хорошо типизировано, ограничено перечислениями, а операция .index
статически типизирована для возврата int
.
Без интерфейса Enum
не было возможности ограничиться только перечислениями и не было доступа к .index
, кроме динамического вызова.
Перечисления по-прежнему ограничены, вы не можете реализовать интерфейс иначе, как путем создания enum
.
Вы можете добавить методы расширения ко всем перечислениям вместо того, чтобы применять методы расширения к каждому конкретному перечислению.
Другой вариант использования: вы можете определить дженерики, которые должны расширяться от Enum, чтобы создавать методы и классы, которые принимают только перечисления.