我正在基于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;
}
}
答案 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;
}