Dart如何获得枚举的"价值"

Nat*_*ood 31 enums dart

在Dart中提供枚举之前,我写了一些繁琐且难以维护的代码来模拟枚举,现在想要简化它.我需要将枚举的值作为字符串获取,例如可以用Java完成,但不能.

例如,当我想要的是"星期一"时,小测试代码片段在每种情况下返回'day.MONDAY'

enum day {MONDAY, TUESDAY}
print( 'Today is $day.MONDAY');
print( 'Today is $day.MONDAY.toString()');
Run Code Online (Sandbox Code Playgroud)

我是否更正为了得到'星期一'我需要解析字符串?

mba*_*rtn 150

Dart 2.7 带有称为扩展方法的新功能。现在您可以为 Enum 编写自己的方法,就这么简单!

enum Day { monday, tuesday }

extension ParseToString on Day {
  String toShortString() {
    return this.toString().split('.').last;
  }
}

main() {
  Day monday = Day.monday;
  print(monday.toShortString()); //prints 'monday'
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*sen 34

短一点:

String day = theDay.toString().split('.').last;
Run Code Online (Sandbox Code Playgroud)

  • 更简单的方法:theDay.toString().split('.').last (11认同)
  • 谢谢,@Hani!您的改进既简单又“安全”。更新了答案。 (2认同)

lrn*_*lrn 25

遗憾的是,你是正确的,toString方法返回"day.MONDAY",而不是更有用"MONDAY".您可以将其余字符串作为:

day theDay = day.MONDAY;      
print("${theDay.toString().substring(theDay.toString().indexOf('.')+1)}");
Run Code Online (Sandbox Code Playgroud)

诚然,这很方便.

如果要迭代所有值,可以使用以下命令day.values:

for (day theDay in day.values) {
  print(theDay);
}
Run Code Online (Sandbox Code Playgroud)


Cop*_*oad 25

enum Day {
  monday,
  tuesday,
}
Run Code Online (Sandbox Code Playgroud)

直接方式:

var dayInString = describeEnum(Day.monday);
print(dayInString); // prints 'monday'
Run Code Online (Sandbox Code Playgroud)

使用扩展:

extension DayEx on Day {
  String get inString => describeEnum(this);
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

void main() {
  Day monday = Day.monday;
  String inString = monday.inString; // 'monday'
}
Run Code Online (Sandbox Code Playgroud)

  • 利用“describeEnum”是可行的方法。使用扩展是一个很好的好处 (4认同)
  • 这应该是第一个答案(当前的第一个答案已过时)。 (2认同)

gbi*_*hue 19

获取枚举名称的最简单方法是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');
}
Run Code Online (Sandbox Code Playgroud)

  • 这只能在 Flutter 中使用。对于仅使用 dart 的代码(使用 dart 而不是 flutter 运行),它将导致错误。 (12认同)

小智 19

enum day {MONDAY, TUESDAY}
print( 'Today is ${describeEnum(day.MONDAY)}' );
Run Code Online (Sandbox Code Playgroud)

控制台输出:今天是星期一


小智 12

有一个更优雅的解决方案:

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"
Run Code Online (Sandbox Code Playgroud)

  • 你说它优雅吗?如何?通过在内存中添加额外的空间和 20 个新行? (18认同)
  • 我其实真的很喜欢这个。其他解决方案似乎很糟糕。 (5认同)
  • 这实际上是一种反模式。当您需要向枚举添加更多值时,您需要在两个地方修改代码,因为您还应该修改映射。想象一下,如果您在一个大型应用程序中有数百个枚举,并且在应用程序的不同部分有数百个映射。很难维护。 (3认同)

jit*_*555 12

如https://medium.com/dartlang/dart-2-17-b216bfc80c5d中所述:

Dart 2.17中,我们现在对枚举成员有了普遍支持。这意味着我们可以添加保存状态的字段、设置该状态的构造函数、具有功能的方法,甚至覆盖现有成员。

例子:

enum Day {
   MONDAY("Monday"),
   TUESDAY("Tuesday");

  const Day(this.text);
  final String text;
}
Run Code Online (Sandbox Code Playgroud)

输出:

void main() {
  const day = Day.MONDAY;
  print(day.text); /// Monday
}
Run Code Online (Sandbox Code Playgroud)

对于上述功能,覆盖 dart 版本,如下所示,目标为 2.17 及更高版本

environment:
  sdk: ">=2.17.0 <3.0.0"
Run Code Online (Sandbox Code Playgroud)


mne*_*c23 9

有时我需要将 ui-value 和 real-value 分开,所以我使用Map. 这样,我们就有了更多的灵活性。通过使用extension(自 Dart 2.7 起),我创建了一种读取其键和值的方法。

enum Status {
  progess,
  done,
}

extension StatusExt on Status {
  static const Map<Status, String> keys = {
    Status.progess: 'progess',
    Status.done: 'done',
  };

  static const Map<Status, String> values = {
    Status.progess: 'In Progress',
    Status.done: 'Well done',
  };

  String get key => keys[this];
  String get value => values[this];

  // NEW
  static Status fromRaw(String raw) => keys.entries
      .firstWhere((e) => e.value == raw, orElse: () => null)
      ?.key;
}

// usage 1
Status status = Status.done;
String statusKey = status.key; // done
String statusValue = status.value; // Well done

// usage 2 (easy to make key and value list)
List<Status> statuses = Status.values;
List<String> statusKeys = statuses.map((e) => e.key).toList();
List<String> statusValues = statuses.map((e) => e.value).toList();

// usage 3. create Status enum from string.
Status done1 = StatusExt.fromRaw('done') // Status.done
Status done2 = StatusExt.fromRaw('dude') // null
Run Code Online (Sandbox Code Playgroud)


Ale*_*hev 7

我使用下面的函数来获取枚举值的名称,反之亦然,通过名称获取枚举值:

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

T enumValueFromString<T>(String key, Iterable<T> values) => values.firstWhere(
      (v) => v != null && key == enumValueToString(v),
      orElse: () => null,
    );
Run Code Online (Sandbox Code Playgroud)

当使用 Dart 2.7 和更新版本时,扩展方法将在这里工作(以及任何其他对象):

extension EnumX on Object {
  String asString() => toString().split('.').last;
}
Run Code Online (Sandbox Code Playgroud)

上面的实现不依赖于特定的枚举。

用法示例:

enum Fruits {avocado, banana, orange}
...
final banana = enumValueFromString('banana', Fruits.values);
print(enumValueToString(banana)); // prints: "banana"
print(banana.asString()); // prints: "banana"
Run Code Online (Sandbox Code Playgroud)

2020 年 4 月 5 日编辑:添加了可空性检查。values参数可能是Iterable,不一定是List。添加了扩展方法实现。<Fruits>从示例中删除了注释以表明不需要类名重复。


Luc*_*rat 7

Dart 2.15 包含一个扩展,可以让这一切变得简单:

enum day {MONDAY, TUESDAY}
print( 'Today is ${day.MONDAY.name}');
Run Code Online (Sandbox Code Playgroud)

在https://github.com/dart-lang/sdk/commit/18f37dd8f3db6486f785b2c42a48dfa82de0948b中的更改推出到 Dart 的稳定版本之前,这里的其他聪明但更复杂的答案非常有用。


Rya*_*ell 6

我克服了这个我做了一个包:

https://pub.dev/packages/enum_to_string

还有一个方便的函数,可以enum.ValueOne将其解析为“ Value one

它是一个简单的小库,但它经过了单元测试,我欢迎为边缘情况添加任何内容。


小智 6

从 dart 2.15 开始只使用“.name”

enum day {monday, tuesday}
print( 'Today is ${day.monday.name}');
Run Code Online (Sandbox Code Playgroud)


Nae*_*Nae 5

我使用如下结构:

class Strings {
  static const angry = "Dammit!";
  static const happy = "Yay!";
  static const sad = "QQ";
}
Run Code Online (Sandbox Code Playgroud)