1

我正在移植一个大量基于 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;
    }

}
4

2 回答 2

1

如果您绝对需要模拟旧的 Java 枚举模式,您可以。然而,Dart 将枚举视为一个更简单的构造。

为了回答您的一个问题,静态字段被“延迟”初始化,因为它们在第一次访问时被初始化。

话虽如此,这是您可以实现您正在尝试做的事情的一种方法。使用 const 构造函数来创建 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']);
}
于 2013-04-19T05:40:37.313 回答
0

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

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

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

在当前的移植尝试中,我发现自己被迫在此类类中添加静态initialModule() 方法,因为它们相互依赖,所以很快就会变得非常讨厌。

在java中,这很容易通过静态代码块来完成,这些代码块保证在加载类时被执行。

在下面使用 ChessColor 的最小示例中,如何在飞镖中得到最好的解决?即_opponent 是如何发起的。

爪哇

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

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;

}
于 2013-05-01T06:46:17.913 回答