Les énumérations

Les Enums sont un types différents de celui des classes et sont déclarés avec un nombre finis de constructeurs. En voici un petit exemple :

    enum Couleur {
        rouge;
        vert;
        bleu;
    }

    class Couleurs {
        static function enChiffres(c:Couleur) : Int {
            return switch(c) {
                case rouge: 0xFF0000;
                case vert: 0x00FF00;
                case bleu: 0x0000FF;

            }
        }
    }

Lorsque quelques couleurs seulement sont requises, les énumérations sont le meilleur outil car ils garantissent que seules ces valeurs pourront être construites.

Constructors parameters

L'exemple Couleur montre trois constructeurs constants pour l'énumération. Mais il est tout à fait possible de mettre des paramètres aux contructeurs :

    enum Couleur2{
        rouge;
        vert;
        bleu;
        gris(v:Int);
        rvb(r:Int, v:Int, b:Int);
    }

De cette manière, il existe une infinité de Couleur2 possibles. Mais il n'existe que cinq constructeurs différents pour les définir. Les valeurs suivantes sont toutes des Couleur2 :

    rouge;
    vert;
    bleu;
    gris(0);
    gris(128);
    rvb(0x00, 0x12, 0x23);
    rvb(0xFF, 0xAA, 0xBB);

Il est aussi possible d'avoir des types récursifs. Par exemple, pour ajouter un canal alpha :

    enum Couleur3 {
        rouge;
        vert;
        bleu;
        gris(v :Int);
        rvb(r:Int, v:Int, b:Int);
        rvbt( col:Couleur3, t:Int);
    }

Ainsi, les valeurs suivantes sont toutes des Couleur3 :

    rvbt(rouge, 127);
    rvbt(rvb(0,0,0), t);

Commutation sur les énumérations

L'expression switch a une sémantique spéciale pour les énumérations. Sans cas default, il faut déclarer tous les constructeurs de l'énumération pour ne pas avoir d'erreur à la compilation. Par exemple, pour l'énumération Couleur :

    switch( c ) {
        case rouge: 0xFF0000;
        case vert: 0x00FF00;
    } //--> erreur de compilation

L'exemple précédent conduira à une erreur de compilation indiquant que le constructeur bleu n'a pas été utilisé. Pour corriger le code, il faudrait soit déclarer un cas pour le constructeur bleu, soit utiliser le cas default. Cette particularité est très appréciable lorsqu'un nouveau constructeur est ajouté à une énumération. Le compilateur affichera tous les endroits où il faudra le traiter.

Commutation sur des constructeurs avec paramètres

Si un constructeur d'une énumération a des paramètres, ils doivent être listés en tant que noms de variables dans un case du switch. De cette manière, les paramètres seront accessibles localement dans l'expression case et seront du même type que dans le constructeur de l'énumération. Voici un exemple basé sur l'énumération Couleur3 :

    class Couleurs {
        static function enChiffres( c : Couleur3 ):Int {
            return switch( c ) {
                case rouge: 0xFF0000;
                case vert: 0x00FF00;
                case bleu: 0x0000FF;
                case gris(v): (v << 16) | (v << 8) | v;
                case rvb(r,v,b): (r << 16) | (v << 8) | b;
                case rvbt(c,t): (t << 24) | (enChiffres(c) & 0xFFFFFF);
            }
        }

    }

Note :switch est la seule manière pour accéder aux paramètres d'un constructeur d'une énumération.

Paramètre de type d'un constructeur d'une énumération

Les énumérations, comme les classes, peuvent avoir un paramètre de type. La syntaxe est la même que celle pour les classes. Voici un exemple de liste chainée paramétrée utilisant une énumération pour empaqueter les cellules :

    enum Cellule<T> {
        vide;
        cons(element:T, suivant:Cellule<T>);
    }

    class ListeChainee<T> {
        var premiere:Cellule<T>;

        public function new() {
            premiere=vide;
        }

        public function ajouter(element:T) {
            premiere = cons(element, premiere);
        }

        public function longueur():Int {
            return longueurCellule(premiere);
        }

        private function longueurCellule( c : Cellule<T> ):Int{
            return switch( c ) {
                case vide : 0;
                case cons(element, suivant): 1 + longueurCellule(suivant);
            }
        }

    }

Le mixage des énumérations et des classes peut être particulièrement efficace dans certains cas.

«« Les Paramètres de type - Les Paquets et Importations »»

version #3978, modified 2008-08-15 19:01:29 by plonstic