# Перечисления

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> {

public function new() {
}

public function add( item : T ) {
}

public function length() : Int {
}

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;
}
}```
version #10075, modified 2011-02-01 16:15:32 by Scythian