Каков вариант использования интерфейса Enum в Dart 2.14?

avatar
Birju Vachhani
9 августа 2021 в 05:47
359
1
1

Я просматривал журналы изменений Dart SDK и заметил это в примечаниях к выпуску Dart SDK v2.14:

enter image description here

Я не смог найти никакой документации по этому поводу! Где я могу это использовать? Я пытался это реализовать, но не получилось!

Источник
julemand101
9 августа 2021 в 06:01
2

Вы можете добавить методы расширения ко всем перечислениям вместо того, чтобы применять методы расширения к каждому конкретному перечислению.

julemand101
9 августа 2021 в 06:26
1

Другой вариант использования: вы можете определить дженерики, которые должны расширяться от Enum, чтобы создавать методы и классы, которые принимают только перечисления.

Ответы (1)

avatar
lrn
9 августа 2021 в 08:01
3

Сценарии использования суперинтерфейса 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.