haXe

Enums

Enums are another type than classes and are declared with a finite number of constructors. Here's a small sample :

    enum Color {
        red;
        green;
        blue;
    }

    class Colors {
        static function toInt( c : Color ) : Int {
            return switch( c ) {
                case red: 0xFF0000;
                case green: 0x00FF00;
                case blue: 0x0000FF;

            }
        }
    }

When you want to ensure that only a fixed number of values are used then enums are the best thing since they guarantee that other values cannot be constructed.

Constructors parameters

The previous Color sample shows three constant constructors for an enum. It is also possible to have parameters for constructors :

    enum Color2 {
        red;
        green;
        blue;
        grey( v : Int );
        rgb( r : Int, g : Int, b : Int );
    }

This way, there is an infinite number of Color2 possible, but they are five different constructors possible for it. The following values are all Color2 :

    red;
    green;
    blue;
    grey(0);
    grey(128);
    rgb( 0x00, 0x12, 0x23 );
    rgb( 0xFF, 0xAA, 0xBB );

We can also have a recursive type, for example to add alpha :

    enum Color3 {
        red;
        green;
        blue;
        grey( v : Int );
        rgb( r : Int, g : Int, b : Int );
        alpha( a : Int, col : Color3 );
    }

The following are valid Color3 values :

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

Switch on Enum

Switch have a special semantic when used on an enum. If there is no default case then it will check that all enum constructor are used, and you'll get an error if not. For example, using the first Color enum :

    switch( c ) {
        case red: 0xFF0000;
        case green: 0x00FF00;
    }

This will cause an compile error telling that the constructor blue is not used. In that case you can either add a case for it or add a default case that does something. It's very useful since when you add a new constructor to your enum, compiler errors will display in your program the places where the new constructor have to be handled.

Switch with Constructor Parameters

If enum constructor have parameters, they must but listed as variable names in a switch case. This way all the variables will be locally accessible in the case expression and corresponding to the type of the enum constructor parameter. For example, using the Color3 enum :

    class Colors {
        static function toInt( c : Color3 ) : Int {
            return switch( c ) {
                case red: 0xFF0000;
                case green: 0x00FF00;
                case blue: 0x0000FF;
                case grey(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);
            }
        }

    }

Using switch is the only possible way to access the enum constructors parameters.

Enum Type Parameters

Enum, as classes, can also have type parameters. The syntax is the same so here's a small sample of a parameterized linked List using an enum to store the cells :

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

    }

Using both enum and classes together can be pretty powerful in some cases.

«« Type Parameters - Packages and Imports »»

version #1747, modified 2008-07-17 02:51:04 by wiering