2013-04-18 105 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; 

}