2013-04-18 104 views
1

我正在大量基于Java枚举移植一个库,并需要编写自己的枚举,直到它们有本地支持。失败枚举尝试

但是我失败了!

在ChessColor.values下面的代码()方法返回null,我不明白为什么。

不过,我是新来省道......

与静态字段和初始化,我已经错过了

一定有什么东西......

枚举的基类

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

退房就如何构建镖枚举这样一个问题:http://stackoverflow.com/q/15854549/1479964 –

+0

看到,但我需要values()和valuOf(String name)所以我做了这个尝试。 –

+0

你有正确的想法。但是我没有看到您使用的所有代码,但我认为这是您运行到https://groups.google.com/a/dartlang.org/d/topic/misc/dKurFjODRXQ/discussion的问题(静态初始化是静态的)所以如果你在访问某个静态值之前调用值,那么构造函数还没有被调用。 –

回答

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']); 
} 
+0

谢谢Seth!我在移植我的java代码时仍然遇到一些问题,请参阅下面的答案。 –

0

所以我从java到dart的移植仍在继续,但我仍然遇到与静态init有关的问题。

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

我相信,一个可以讨论这样的设计,但它会导致当谈到写的象棋代码清洁和漂亮的代码。

在当前的移植尝试,我发现自己不得不添加静态initiateModule()方法,这样的类成为讨厌的真正快速,因为它们是互相依赖的。

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

飞镖

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; 

}