Enums

Enums are different to classes and are declared with a finite number of constructors. Here's a small example:

    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's possible, but there 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

A switch has a special behavior when used on an enum. If there is no default case then it will check that all an enum's constructors are used within the switch, and if not the compiler will generate a warning. For example, consider the first Color enum :

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

This will cause a compile errorwarning that the constructor blue is not used. In this example you can either add a case for it or add a default case that does something. This can be quite useful, as when you add new constructors to your enum, compiler errors will alert you to areas in your program where the new constructor should be handled.

Switch with Constructor Parameters

If enum constructor have parameters, they must be listed as variable names in a switch case. This way all the variables will be locally accessible in the case expression and correspond 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

An Enum 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 enums and classes together can be pretty powerful in some cases.

Using Enums as default value for parameters

Because an Enum's values are in fact created from a constructor they are not constant and therefore cannot be used as default value for a parameter. However there's a simple work-around :

    enum MyEnum {
        myFirstValue;
        mySecondValue;
    }

    class Test {
        static function withDefaultValuesOnParameters(?a : MyEnum) {
            if(a == null)
                a = MyEnum.myFirstValue;
        }
    }

«« Type Parameters - Packages and Imports »»

version #6953, modified 2009-09-05 17:26:16 by justsee