如何使用 Dart 构建枚举? [复制]

Posted

技术标签:

【中文标题】如何使用 Dart 构建枚举? [复制]【英文标题】:How can I build an enum with Dart? [duplicate] 【发布时间】:2013-03-29 02:03:28 【问题描述】:

Dart 语言没有枚举(还没有??)。至少在语言特性出现之前,构造枚举的正确或惯用方式是什么?

【问题讨论】:

从 Dart 1.8 开始,您现在可以使用正式的枚举。请参阅下面接受的答案。 【参考方案1】:

Dart 现在支持枚举

此答案的其余部分适用于 Dart 1.8,请使用 Dart 对枚举的正式支持(在另一个答案中解释)。

确实,Dart 语言(还没有?)没有枚举。它有一个open issue。

同时,这里有一个惯用的 Dart sn-p 来创建你自己的枚举。

class Enum 
  final _value;
  const Enum._internal(this._value);
  toString() => 'Enum.$_value';

  static const FOO = const Enum._internal('FOO');
  static const BAR = const Enum._internal('BAR');
  static const BAZ = const Enum._internal('BAZ');

使用 const 构造函数意味着您可以在开关中使用此枚举。这是一个例子:

class Fruits 
  final _value;
  const Fruits._internal(this._value);
  toString() => 'Enum.$_value';

  static const APPLE = const Fruits._internal('APPLE');
  static const PEAR = const Fruits._internal('PEAR');
  static const BANANA = const Fruits._internal('BANANA');


void main() 
  var yummy = Fruits.BANANA;

  switch (yummy) 
    case Fruits.APPLE:
      print('an apple a day');
      break;
    case Fruits.PEAR:
      print('genus Pyrus in the family Rosaceae');
      break;
    case Fruits.BANANA:
      print('open from the bottom, it is easier');
      break;
  

【讨论】:

小警告:创建没有任何值的 const 对象是常见错误。例如“class Enum const Enum(); ”。这是行不通的,因为 Dart 规范了常量对象。因此,请始终确保有一个可以区分各个枚举值的值。 yummy =='BANANA' 返回 false... 真可惜... :/ Dart 现在实验性地支持枚举:news.dartlang.org/2014/11/dart-18-library-improvements-and.html @AnthonyBobenrieth 是的。但是如果你为 _value 添加一个 getter,你可以做 yummy.value == 'BANANA'。 是否可以添加fromString(String) 构造函数?我尝试添加const factory Fruits.fromString(String s) = _internal;,但它似乎创建的实例不等于APPLEPEARBANANA...【参考方案2】:

随着 r41815 Dart 获得原生 Enum 支持,请参阅 http://dartbug.com/21416 并且可以像这样使用

enum Status 
  none,
  running,
  stopped,
  paused


void main() 
  print(Status.values);
  Status.values.forEach((v) => print('value: $v, index: $v.index'));
  print('running: $Status.running, $Status.running.index');
  print('running index: $Status.values[1]');

[Status.none、Status.running、Status.stopped、Status.paused] 值:Status.none,索引:0 值:Status.running,索引:1 值:Status.stopped,索引:2 值:Status.paused,索引:3 运行:Status.running,1 运行索引:Status.running

限制是不可能为枚举项设置自定义值,它们会自动编号。

更多详情请参阅本草案https://www.dartlang.org/docs/spec/EnumsTC52draft.pdf

【讨论】:

【参考方案3】:

我在Dart Web Toolkit 中使用了更简单的 Enum 类版本:

/**
 * Emulation of Java Enum class.
 *
 * Example:
 *
 * class Meter<int> extends Enum<int> 
 *
 *  const Meter(int val) : super (val);
 *
 *  static const Meter HIGH = const Meter(100);
 *  static const Meter MIDDLE = const Meter(50);
 *  static const Meter LOW = const Meter(10);
 * 
 *
 * and usage:
 *
 * assert (Meter.HIGH, 100);
 * assert (Meter.HIGH is Meter);
 */
abstract class Enum<T> 

  final T _value;

  const Enum(this._value);

  T get value => _value;

【讨论】:

我喜欢枚举的***常量。您可以使用导入来修复任何冲突。这使得使用枚举不那么冗长。编辑 - 添加了一个示例。 加个方法可以吗:toString() => value; ?【参考方案4】:

我喜欢枚举的***常量。您可以使用导入来修复任何冲突。这使得使用枚举不那么冗长。

if (m == high) 

代替:

if (m == Meter.high) 

枚举定义:

class Meter<int> extends Enum<int> 
   const Meter(int val) : super (val);


const Meter high = const Meter(100);
const Meter middle = const Meter(50);
const Meter low = const Meter(10);

【讨论】:

这是个好主意吗?我觉得使用导入来清除被污染的命名空间不是大型项目的方式

以上是关于如何使用 Dart 构建枚举? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dart 中按“枚举”对列表进行排序?

如何在 Dart 中提供 Future<String> 来流式传输需要 String 的流? [复制]

dart 中的 json_serializable 枚举值

如何在 Dart 中格式化日期? [复制]

如何在 Dart 的流构建器中切换我正在收听的流?

如何使用 JPA 将 MySQL 枚举映射到 Java 枚举? [复制]