Дарт Как получить "значение" перечисления

Прежде чем перечисления были доступны в Dart, я написал несколько громоздких и сложных для поддержания кода для имитации перечислений и теперь хочу его упростить. Мне нужно получить значение enum как строку, например, которую можно выполнить с помощью Java, но не может.

Например, небольшой фрагмент кода кода возвращает "day.MONDAY" в каждом случае, когда я хочу "MONDAY"

enum day {MONDAY, TUESDAY}
print( 'Today is $day.MONDAY');
print( 'Today is $day.MONDAY.toString()');

Я исправлю это, чтобы получить "MONDAY", мне нужно будет разобрать строку?

Ответ 1

К сожалению, вы правы, что метод toString возвращает "day.MONDAY", а не более полезный "MONDAY". Вы можете получить остальную часть строки как:

day theDay = day.MONDAY;      
print("${theDay.toString().substring(theDay.toString().indexOf('.')+1)}");

Вряд ли удобный, по общему признанию.

Если вы хотите итерировать все значения, вы можете сделать это, используя day.values:

for (day theDay in day.values) {
  print(theDay);
}

Ответ 2

Немного короче:

String day = theDay.toString().split('.').last;

Ответ 3

Самый простой способ получить имя перечисления - это стандартный метод из flutter/foundation.dart

describeEnum(enumObject)

enum Day {
  monday, tuesday, wednesday, thursday, friday, saturday, sunday
}

void validateDescribeEnum() {
  assert(Day.monday.toString() == 'Day.monday');
  assert(describeEnum(Day.monday) == 'monday');
}

Ответ 4

Есть более элегантное решение:

enum SomeStatus {
  element1,
  element2,
  element3,
  element4,
}

const Map<SomeStatus, String> SomeStatusName = {
  SomeStatus.element1: "Element 1",
  SomeStatus.element2: "Element 2",
  SomeStatus.element3: "Element 3",
  SomeStatus.element4: "Element 4",
};

print(SomeStatusName[SomeStatus.element2]) // prints: "Element 2"

Ответ 5

Я использую структуру, как показано ниже:

class Strings {
  static const angry = "Dammit!";
  static const happy = "Yay!";
  static const sad = "QQ";
}

Ответ 6

Я получил за это, я сделал пакет:

https://pub.dev/packages/enum_to_string

Также есть удобная функция, которая принимает enum.ValueOne и анализирует его как "Value one"

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

Ответ 7

Мой подход не принципиально отличается, но может быть немного более удобным в некоторых случаях:

enum Day {
  monday,
  tuesday,
}

String dayToString(Day d) {
  return '$d'.split('.').last;
}

В Dart вы не можете настроить метод enSt toString, поэтому я думаю, что этот обходной путь вспомогательной функции необходим, и он является одним из лучших подходов. Если вы хотите быть более корректным в этом случае, вы можете сделать первую букву возвращаемой строки заглавными.

Вы также можете добавить функцию dayFromString

Day dayFromString(String s) {
  return Day.values.firstWhere((v) => dayToString(v) == s);
}

Пример использования:

void main() {
  Day today = Day.monday;
  print('Today is: ${dayToString(today)}');
  Day tomorrow = dayFromString("tuesday");
  print(tomorrow is Day);
}

Ответ 8

Я использую эти две функции, чтобы получить имя значения enum и, наоборот, значение enum по имени:

String enumValueToString(Object o) => o.toString().split('.').last;

T enumValueFromString<T>(String key, List<T> values) =>
    values.firstWhere((v) => key == enumValueToString(v), orElse: () => null);

Примеры использования:

enum Fruits {avocado, banana, orange}
...
final banana = enumValueFromString<Fruits>('banana', Fruits.values);
print(enumValueToString(banana)); // prints: "banana"

Ответ 9

У меня была такая же проблема в одном из моих проектов, и существующие решения были не очень чистыми, и он не поддерживал расширенные функции, такие как сериализация/десериализация json.

Flutter изначально не поддерживает enum со значениями, однако мне удалось разработать вспомогательный пакет Vnum, использующий реализацию классов и отражателей для решения этой проблемы.

Обратитесь в хранилище:

https://github.com/AmirKamali/Flutter_Vnum

Чтобы ответить на вашу проблему, используя Vnum, вы можете реализовать свой код, как показано ниже:

@VnumDefinition
class Visibility extends Vnum<String> {
  static const VISIBLE = const Visibility.define("VISIBLE");
  static const COLLAPSED = const Visibility.define("COLLAPSED");
  static const HIDDEN = const Visibility.define("HIDDEN");

  const Visibility.define(String fromValue) : super.define(fromValue);
  factory Visibility(String value) => Vnum.fromValue(value,Visibility);
}

Вы можете использовать его как:

var visibility = Visibility('COLLAPSED');
print(visibility.value);

В репозитории github есть больше документации, надеюсь, она вам поможет.