Enums 飞镖如何获得“飞镖”;“价值”;枚举的

Enums 飞镖如何获得“飞镖”;“价值”;枚举的,enums,dart,Enums,Dart,在Dart中提供枚举之前,我编写了一些繁琐且难以维护的代码来模拟枚举,现在我想简化它。我需要以字符串的形式获取枚举的值,例如可以用Java完成,但不能 例如,当我想要的是“星期一”时,小测试代码段在每种情况下都返回“day.MONDAY” 我是否正确,为了得到“星期一”,我需要解析字符串?遗憾的是,您正确地认为toString方法返回的是“day.MONDAY”,而不是更有用的“MONDAY”。 您可以通过以下方式获取字符串的其余部分: day theDay=day.MONDAY; 打印(day

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

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


我是否正确,为了得到“星期一”,我需要解析字符串?

遗憾的是,您正确地认为toString方法返回的是
“day.MONDAY”
,而不是更有用的
“MONDAY”
。 您可以通过以下方式获取字符串的其余部分:

day theDay=day.MONDAY;
打印(day.toString().substring(theDay.toString().indexOf('.')+1));
无可否认,这很不方便

另一种将枚举名称获取为字符串的方法是,该方法较短,但效率较低,因为它也会为字符串的第一部分创建一个不必要的字符串:

theDay.toString().split('.').last
如果性能不重要,我可能会这么写,只是为了简洁

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

for(day中的day.values){
打印(当日);
}
稍微短一点:

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

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

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"
enum SomeStatus{
要素1,
要素2,
要素3,
要素4,
}
常量映射SomeStatusName={
SomeStatus.element1:“元素1”,
SomeStatus.element2:“元素2”,
SomeStatus.element3:“元素3”,
SomeStatus.element4:“Element 4”,
};
print(SomeStatusName[SomeStatus.element2])//打印:“Element 2”

我使用如下结构:

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

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

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);
}

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

String enumValueToString(对象o)=>o.toString().split('.').last;
T enumValueFromString(字符串键,Iterable值)=>values.firstWhere(
(v) =>v!=null&&key==enumValueToString(v),
orElse:()=>null,
);
当使用Dart 2.7及更新版本时,扩展方法将在此处(以及任何其他对象)起作用:

对象上的扩展EnumX{ 字符串asString()=>toString().split('.').last; } 上述实现不依赖于特定的枚举

用法示例:

enum水果{鳄梨、香蕉、橘子}
...
final banana=enumValueFromString('banana',Fruits.values);
打印(enumValueToString(香蕉));//打印:“香蕉”
print(banana.asString());//prints:“banana”

从2020年4月5日开始编辑:添加了可空性检查。
值可以是
Iterable
,不一定是
List
。添加了扩展方法实现。从示例中删除了
注释,以表明不需要复制类名。

获取枚举名称的最简单方法是sta颤振/基础.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');
}

我受够了,我做了一个包裹:

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


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

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

flatter本机目前不支持带有值的enum,但是,我设法使用类和反射器实现开发了一个helper包
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);
}

github repo中有更多文档,希望能对您有所帮助。

Dart 2.7附带了名为的新功能。现在,您可以编写自己的枚举方法,就这么简单

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'
}

我们不必为每个枚举定义扩展,而是可以在对象上定义扩展,并从任何枚举访问
.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("_", " ");
}
有了它,您甚至可以定义多单词枚举,其中单词在其名称中用
(下划线)分隔。

enum Day{
enum day {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);
星期一, 星期二, }
直接方式:

var dayInString=descripbeenum(Day.monday);
打印(dayInString);//打印“星期一”

使用扩展名:

日扩展日{
字符串get inString=>descripbeenum(这个);
}
您可以像这样使用它:

void main(){
Day monday=Day.monday;
字符串inString=monday.inString;//“monday”
}

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

创建一个类来帮助:

class Enum {
    Enum._();

    static String name(value) {
        return value.toString().split('.').last;
    }
}
并致电:

Enum.name(myEnumValue);

有时我需要将ui值和实际值分开,所以我使用
Map
定义了键和值。这样,我们就有了更大的灵活性。通过使用
扩展
(从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
enum状态{
进步,
完成,
}
扩展状态EXT on状态{
静态常量映射键={
Status.proges:“proges”,
Status.done:'done',
};
静态常量映射值={
Status.proges:“正在进行中”,
Status.done:“干得好”,
};
字符串get key=>keys[this];
字符串get value=>values[this];
//新的
静态状态fromRaw(stringraw)=>keys.entries
.firstWhere((e)=>e.value==raw,或lse:()=>null)
钥匙
}
//用法1
Status Status=Status.done;
字符串statusKey=status.key;//完成
字符串状态
class Enum {
    Enum._();

    static String name(value) {
        return value.toString().split('.').last;
    }
}
Enum.name(myEnumValue);
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
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;
  }
}
// convert enum value to string
print(TestEnum.test.enumValue);

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