Haxe入門 / Enum Instance
2.4 Enum Instance 列挙インスタンス
Haxeはデータ構造を表現するための強力な列挙型がある。いわゆる代数的データ型(ADT: algebraic data type)。でもこんな難しい言葉は無視しても良いと思います。
列挙型は式を持てないことに注意。
enum Color {
Red;
Green;
Blue;
Rgb(r:Int, g:Int, b:Int);
}
この列挙型Colorは、Red, Green, Blue, あるいはRGBで指定した任意の色、のいずれかを表す。順にコードを説明すると、
enumキーワードで列挙型を宣言。Colorは列挙型の名前。型指定子として使える名前であればなんでも取れる。なぜかリンク先に何も書いてないが、型指定子については式の方にそれっぽい記述がある。{}で囲まれた中身を、enum constructors (列挙コンストラクタ)という。Red, Green, Blueは引数なし。Rgbは3つのInt型引数r, g, bを取る。
Colorが列挙型、{...}の中身が列挙コンストラクタ
Haxeの型システムには、すべての列挙型を統一的に扱う型Enum<T>がある。
Enum<T>はコンパイル時にすべての列挙型に共通な基底型とされる。
例えば、Enum<Color>という型のインスタンスはColorという型。
var x: Enum<Color> = Color; // OK trace(Type.allEnums(x)); // [Red,Green,Blue]
他の言語にもあったりするけど、型のインスタンスが型というのは馴染みがないかも。
ただし、Haxeコンパイラによって生成されたコードにはEnum<T>と個別の列挙型との関係は反映されない。(という解釈であってる?)
2.4.1 Enum Constructor 列挙コンストラクタ
クラスの場合と同じように、列挙コンストラクタを使うと列挙型のインスタンスを作れる。ただしクラスとは違って列挙型には複数のコンストラクタ(Red, Green, Blue, Rgb)があるので、そのうちのどれかを使ってインスタンス化する。
var a = Red; var b = Green; var c = Rgb(255, 255, 0);
この例では変数a, b, cの型はColor。変数cはRgbコンストラクタを使って初期化されている。
すべての列挙インスタンスの型はEnumValueという特殊な型でもある。Haxe標準ライブラリはこのEnumValueを使って列挙インスタンスに対する統一的な演算方法を定義してる。
列挙型と列挙コンストラクタには重要な違いがある。
import Color;
class EnumUnification {
static public function main() {
var ec:EnumValue = Red; // valid
var en:Enum<Color> = Color; // valid
//var x:Enum<Color> = Red; // ※ Compile Error: Color should be Enum<Color>
}
}
このコードの7行目(※)をコメントアウトするとコンパイルは通らない。
何故かというと、Redは列挙コンストラクタで、Enum<Color>は列挙型だから。列挙コンストラクタを列挙型に代入することはできない。クラスでいう、クラスのインスタンスをクラスの型に代入できないのと同じ。