Dart如何获得枚举的“价值”

时间:2015-04-10 17:22:30

标签: enums dart

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

例如,当我想要的是“星期一”时,小测试代码片段会返回'day.MONDAY'

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

我是否认为只要'星期一'我需要解析字符串?

19 个答案:

答案 0 :(得分:15)

遗憾的是,你是正确的,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);
}

答案 1 :(得分:9)

这是您的枚举:

enum Day {
  monday,
  tuesday,
}

创建扩展名(可能需要import 'package:flutter/foundation.dart';

extension DayEx on Day {
  String get inString => describeEnum(this);
}

用法:

void main() {
  Day monday = Day.monday;
  String inString = monday.inString; // 'monday'
}

答案 2 :(得分:8)

短一点:

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

答案 3 :(得分:6)

有时我需要将 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

答案 4 :(得分: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 :(得分:3)

另一种方式:

DataStreamSource<String> source = 
  env.fromSource(
    FileSource.forRecordStreamFormat(
      new TextLineFormat(),
      new Path("file:///Users/user/file.txt")
    ).build(),
    WatermarkStrategy.noWatermarks(),
    "MySourceName"
  );

答案 6 :(得分:2)

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

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

答案 7 :(得分:1)

Dart 2.7带有称为Extension methods的新功能。现在,您可以像这样简单地为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'
}

答案 8 :(得分:1)

我们可以为对象定义扩展,而不是为每个枚举定义扩展名,并且可以从任何枚举访问.enumValue

void main() {

  // ❌ Without Extension ❌

  print(Countries.Cote_d_Ivoire.toString().split('.').last.replaceAll("_", " ")); // Cote d Ivoire
  print(Movies.Romance.toString().split('.').last.replaceAll("_", " ")); //Romance


  // ✅ With Extension ✅

  print(Countries.Cote_d_Ivoire.enumValue); // Cote d Ivoire
  print(Movies.Romance.enumValue); //Romance
}

enum Countries { United_States, United_Kingdom, Germany, Japan, Cote_d_Ivoire }
enum Movies { Romance, Science_Fiction, Romantic_Comedy, Martial_arts }

extension PrettyEnum on Object {
  String get enumValue => this.toString().split('.').last.replaceAll("_", " ");
}

使用此功能,您甚至可以定义多词枚举,其中单词名称之间用_(下划线)分隔。

答案 9 :(得分:1)

enum day {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);

答案 10 :(得分:1)

创建一个类来帮助:

class Enum {
    Enum._();

    static String name(value) {
        return value.toString().split('.').last;
    }
}

并致电:

Enum.name(myEnumValue);

答案 11 :(得分:0)

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

答案 12 :(得分:0)

为此,我做了一个包裹:

https://pub.dev/packages/enum_to_string

还有一个方便的功能,可将enum.ValueOne解析为“ Value one

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

答案 13 :(得分:0)

我在一个项目中遇到了同样的问题,现有的解决方案不是很干净,并且不支持json序列化/反序列化等高级功能。

Flutter本机目前不支持带有值的枚举,但是,我设法使用类和反射器实现来开发辅助程序包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仓库中还有更多文档,希望对您有所帮助。

答案 14 :(得分:0)

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

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"

答案 15 :(得分:0)

我的方法没有本质上的不同,但在某些情况下可能会更方便一些:

enum Day {
  monday,
  tuesday,
}

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

在Dart中,您无法自定义枚举的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);
}

答案 16 :(得分:0)

现在有了空安全,它看起来像这样

String enumToString(Object? o) => o != null ? o.toString().split('.').last : '';


T? enumFromString<T>(String key, List<T> values) {
  try {
    return values.firstWhere((v) => key == enumToString(v));
  } catch(e) {
    return null;
  }
}

答案 17 :(得分:0)

您可以查看此包enum_object

// convert enum value to string
print(TestEnum.test.enumValue);

// convert String to enum value
var enumObject = EnumObject<TestEnum>(TestEnum.values);
print(enumObject.enumFromString('test2'));```

答案 18 :(得分:0)

我使用如下结构:

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