2013-04-18 4 views
1

Je suis en train de porter une bibliothèque fortement basée sur des enums Java et j'ai besoin de coder ma propre énumération jusqu'à ce qu'il y ait un support natif pour eux.Échec de tentative d'énumération

Cependant, j'échoue!

Dans le code ci-dessous, la méthode ChessColor.values ​​() renvoie null et je ne vois pas pourquoi.

Cependant, je suis nouveau à Dart ...

Il doit y avoir quelque chose avec les champs statiques et initialisation que j'ai manqué ...

Enum classe de base

part of chessmodel; 

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

    final int code; 
    final String name; 

    Enum(this.code, this.name);  

    toString() => name;  

} 

Une simple utilisation essayer

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

Vérifiez cette question sur la façon de construire énumérations dans fléchette: http://stackoverflow.com/q/15854549/1479964 –

+0

Saw, mais je dois the values ​​() et valuOf (String name) donc j'ai fait cette tentative. –

+0

Et vous avez la bonne idée.Mais je n'ai pas vu tout le code que vous utilisez mais je pense que c'est le problème que vous rencontrez https://groups.google.com/a/dartlang.org/d/topic/misc/dKurFjODRXQ/discussion (Les statistiques sont initialisées paresseux) donc si vous appelez des valeurs avant d'avoir accédé à l'une des valeurs statiques, le constructeur n'est pas encore appelé. –

Répondre

1

Si vous avez absolument besoin d'émuler l'ancien modèle Java, vous pouvez le faire. Cependant, Dart considère les énumérations comme une construction beaucoup plus simple.

Pour répondre à une de vos questions, les champs statiques sont initialisés "paresseusement", en ce sens qu'ils sont initialisés lors de leur premier accès. Cela étant dit, voici une façon de mettre en œuvre ce que vous essayez de faire. Utilisez les constructeurs const pour créer des objets const. Les objets Const sont canonisés par le compilateur. Cela signifie que deux objets const qui sont initialisés de la même manière sont en fait le même objet exact. Généralement, vous voulez que les enums soient 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

Merci Seth pour ça! J'ai toujours quelques problèmes avec le portage de mon code java voir ma réponse ci-dessous. –

0

Donc, mon portage de Java darder se passe mais j'ai encore des problèmes liés à initialisation statique.

Mes Java enums étaient intelligents. C'est à dire. ChessSquare A2 connaît ses voisins. ChessBoardDirection sait que c'est la direction opposée. ChessColor connait les couleurs de son adversaire, etc.

Je suis sûr que l'on peut débattre d'un tel design mais cela conduit à un code propre et agréable quand il s'agit d'écrire du code d'échecs.

Dans la tentative de portage en cours, je me suis vu obligé d'ajouter des méthodes staticModule() statiques dans de telles classes qui deviennent méchantes rapidement car elles dépendent les unes des autres.

En Java, cela se fait facilement avec des blocs de code statiques qui sont garantis être exécuté lorsque la classe est chargée.

Dans l'exemple minimal ci-dessous avec ChessColor, comment cela se résout-il le mieux en dart? I.e. comment est initié le _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; 

} 
Questions connexes