Enums

Las enumeraciones son diferentes a las clases y se declaran con un número finito de constructores. Aquí tenemos un pequeño ejemplo:

    enum Color {
        rojo;
        verde;
        azul;
    }

    class Colores {
        static function toInt( c : Color ) : Int {
            return switch( c ) {
                case rojo: 0xFF0000;
                case verde: 0x00FF00;
                case azul: 0x0000FF;

            }
        }
    }

Cuando quieras asegurarte de que sólo se usan unos valores concretos entonces las enumeraciones son lo mejor porque garantizan que no se pueden construir otros valores.

Parámetros constructores

El ejemplo Color anterior muestra tres constructores constantes para una enum. También es posible tener parámetros en los constructores :

    enum Color2 {
        rojo;
        verde;
        azul;
        gris( v : Int );
        rgb( r : Int, g : Int, b : Int );
    }

De esta manera, hay un número infinito posible de Color2's, pero sólo hay cinco constructores disponibles para ello. Los siguientes valores son todos Color2:

    rojo;
    verde;
    azul;
    gris(0);
    gris(128);
    rgb( 0x00, 0x12, 0x23 );
    rgb( 0xFF, 0xAA, 0xBB );

También podemos tener un tipo recursivo, por ejemplo para añadir alpha :

    enum Color3 {
        rojo;
        verde;
        azul;
        gris( v : Int );
        rgb( r : Int, g : Int, b : Int );
        alpha( a : Int, col : Color3 );
    }

Éstos son valores Color3 válidos :

    alpha( 127, red );
    alpha( 255, rgb(0,0,0) );

Switch sobre enumeraciones

Un switch se comporta de manera especial cuando se usa sobre una enumeración. Si no hay un caso default entonces comprobará que se usen todos los constructores de la enumeración dentro del switch y, si no, el compilador generará un aviso. Por ejemplo, consideremos la primera enum Color :

    switch( c ) {
        case rojo: 0xFF0000;
        case verde: 0x00FF00;
    }

Esto provocará un error de compilación advirtiendo de que no se incluyó el constructor blue. En este ejemplo podemos añadir un caso para él o uno por omisión que no haga nada. Esto puede ser bastante útil, ya que cuando añadas nuevos constructores a una enum, los errores de compilación te avisarán de partes de tu programa en que debería tenerse en cuenta el nuevo constructor.

Switch con parámetros constructores

Si un constructor de la enumeración tiene parámetros, deben aparecer listados como nombres de variable en un caso del switch. De esta manera, todas las variables serán accesibles de manera local en la expresión case y corresponderán al tipo del parámetro del constructor de la enum. Por ejemplo, haciendo uso de Color3:

    class Colores {
        static function toInt( c : Color3 ) : Int {
            return switch( c ) {
                case rojo: 0xFF0000;
                case verde: 0x00FF00;
                case azul: 0x0000FF;
                case gris(v): (v << 16) | (v << 8) | v;
                case rgb(r,g,b): (r << 16) | (g << 8) | b;
                case alpha(a,c): (a << 24) | (toInt(c) & 0xFFFFFF);
            }
        }

    }

Hacer uso de switch es la única manera posible de acceder a los parámetros de los constructores de una enum.

Parámetros de tipo Enum

Una enumeración también puede tener parámetros de tipo. La sintaxis es la misma así que aquí tienes un pequeño ejemplo de Lista enlazada parametrizada que usa una enum para almacenar las celdas :

    enum Cell<T> {
        empty;
        cons( item : T, next : Cell<T> );
    }

    class List<T> {
        var head : Cell<T>;

        public function new() {
            head = empty;
        }

        public function add( item : T ) {
            head = cons(item,head);
        }

        public function length() : Int {
            return cell_length(head);
        }

        private function cell_length( c : Cell<T> ) : Int {
            return switch( c ) {
            case empty : 0;
            case cons(item,next): 1 + cell_length(next);
            }
        }

    }

El uso de enums y clases juntas puede ser bastante potente en ciertos casos.

Uso de Enums como valor por omisión para parámetros

Dado que los valores de las Enum se crean en realidad mediante un constructor no son constantes y por tanto no se pueden usar como valor por omisión para un parámetro. Sin embargo, hay un parche sencillo para eso :

    enum MiEnum {
        miPrimerValor;
        miSegundoValor;
    }

    class Test {
        static function conValoresPorOmisionEnParametros(?a : MiEnum) {
            if(a == null)
                a = MiEnum.miPrimerValor;
        }
    }

«« Parámetros de tipo - Packages and Imports »»

version #7420, modified 2009-12-28 01:32:29 by Heimy