枚举尝试失败

时间:2013-04-18 12:59:21

标签: enums dart

我正在基于Java枚举大量移植一个库,需要编写自己的枚举,直到有对它们的原生支持。

但是我失败了!

在下面的代码中,ChessColor.values()方法返回null,我看不出原因。

但我是Dart的新手......

必须有一些我已经错过的静态字段和初始化...

枚举基类

part of chessmodel;

/**
 * Emulation of Java Enum class.
 */
abstract class Enum {    

  final int code;
  final String name;

  Enum(this.code, this.name);    

  toString() => name;    

}

一个简单的用法尝试

part of chessmodel;

final ChessColor WHITE = ChessColor.WHITE;
final ChessColor BLACK = ChessColor.BLACK;

class ChessColor extends Enum {

  static List<ChessColor> _values;
  static Map<String, ChessColor> _valueByName;

  static ChessColor WHITE = new ChessColor._x(0, "WHITE");
  static ChessColor BLACK = new ChessColor._x(1, "BLACK");

  ChessColor._x(int code, String name) : super (code, name) {
    if (_values == null) {
      _values = new List<ChessColor>();
      _valueByName = new Map<String, ChessColor>();
    }
    _values.add(this);
    _valueByName[name] = this;
  }

  static List<ChessColor> values() {
    return _values;
  }

  static ChessColor valueOf(String name) {
    return _valueByName [name];
  }

    ChessColor opponent() {
        return this == WHITE ? BLACK : WHITE;
    }

    bool isWhite() {
        return this == WHITE;
    }

    bool isBlack() {
        return this == BLACK;
    }

}

2 个答案:

答案 0 :(得分:1)

如果您绝对需要模拟旧的Java枚举模式,则可以。但是,Dart将枚举看作一个更简单的结构。

要回答您的一个问题,静态字段会“懒洋洋地”初始化,因为它们是在首次访问时初始化的。

话虽这么说,这是你可以实现你想要做的事情的一种方式。使用const构造函数创建const对象。 Const对象由编译器规范化。这意味着以相同方式初始化的两个const对象实际上是完全相同的对象。通常,您希望枚举为常量。

/**
 * Emulation of Java Enum class.
 */
abstract class Enum {    

  final int code;
  final String name;

  const Enum(this.code, this.name);    

  String toString() => name;
}

final ChessColor WHITE = ChessColor.WHITE;
final ChessColor BLACK = ChessColor.BLACK;

class ChessColor extends Enum {

  static const List<ChessColor> values =
      const [ChessColor.WHITE, ChessColor.BLACK];
  static Map<String, ChessColor> valueByName =
      const {"WHITE": ChessColor.WHITE, "BLACK": ChessColor.BLACK};

  static const ChessColor WHITE = const ChessColor._x(0, "WHITE");
  static const ChessColor BLACK = const ChessColor._x(1, "BLACK");

  const ChessColor._x(int code, String name) : super (code, name);
}

void main() {
  print(WHITE);
  print(ChessColor.values);
  print(ChessColor.WHITE.code);
  print(ChessColor.valueByName['BLACK']);
}

答案 1 :(得分:0)

所以我从java移植到dart继续,但我仍然遇到与静态初始化相关的问题。

我的Java知道哪里聪明。即ChessSquare A2知道它的邻居。 ChessBoardDirection知道它是相反的方向。 ChessColor知道对手的颜色等等。

我确信人们可以讨论这样的设计,但在编写国际象棋代码时会产生干净和漂亮的代码。

在当前的移植尝试中,我发现自己被迫在这些类中添加静态的initModule()方法,这些方法因为相互依赖而变得非常快速。

在java中,这可以通过保证在加载类时执行的静态代码块轻松完成。

在下面的最小例子中,使用ChessColor,如何最好地解决飞镖问题? 即_opponent是如何发起的。

Java

package chess.model;

public enum ChessColor {
  WHITE, BLACK;

  private ChessColor opponent;

  public ChessColor opponent() {
    return opponent;
  }

  public boolean isWhite() {
    return this == WHITE;
  }

  public boolean isBlack() {
    return this == BLACK;
  }

  static { // Initiate cross dependencies
    WHITE.opponent = BLACK;
    BLACK.opponent = WHITE;
  }
}

Dart

part of chessmodel;

final ChessColor WHITE = ChessColor.WHITE;
final ChessColor BLACK = ChessColor.BLACK;

class ChessColor extends Enum {

  static ChessColor WHITE = new ChessColor._x(0, "WHITE");
  static ChessColor BLACK = new ChessColor._x(1, "BLACK");

  static List<ChessColor> _values = [WHITE, BLACK];
  static Map<String, ChessColor> _valueByName = {"WHITE": WHITE, "BLACK": BLACK};

  ChessColor _opponent;

  ChessColor._x(int code, String name) : super (code, name);

  static List<ChessColor> values() {
    return _values;
  }

  static ChessColor valueOf(String name) {
    return _valueByName [name];
  }

  ChessColor get opponent => _opponent; 
  bool get isWhite => this == WHITE;
  bool isBlack => this == BLACK;

}
相关问题