Haxe3の新機能

抽象型(abstract)

  • 説明: 抽象型は、実行時には消失して他の抽象型でない型によって表される型です。Haxe3では、暗黙のキャスト演算子オーバーロードカスタム配列アクセスなどきめ細かい定義を可能にします。
  • :
    @:coreType 
    abstract Kilometer from Int to Int { }
    
    class Main {
        static function main() {
            var km:Kilometer = 1;
            var n:Float = km;
        }
    }
  • 詳細: 抽象型(abstract)

配列内包表記

  • 説明: 配列内包の構文により、可読性を保ったまま簡潔に配列の初期化が行えるようになります。この構文は他の言語では軽視されがちな構文で、for、while、ifを配列宣言"[]"の内側で展開します。
  • :
    // 0~20の偶数
    var a = [for (i in 0...21) if (i & 1 == 0) i];
    trace(a); // [0,2,4,6,8,10,12,14,16,18,20]
    
    // ファイルパスの配列 (haxe.io.Pathを使用)
    var path = "/top/bar/foo/File.hx";
    var pathParts = [while ((path = haxe.io.Path.directory(path)) != "") path];
    trace(pathParts); // [/top/bar/foo,/top/bar,/top]

ジェネリック関数

  • 説明: Haxe3では@:genericメタデータが関数でも使用可能になりました。@:genericはクラスの場合と同じように動作します。つまり、関数が指定された型パラメータに特化されて、静的なプラットフォームではパフォーマンスが改善されます。おまけに、newを持つことを強制することで、型パラメータのコンストラクタを呼び出すことも可能になります。
  • :
        @:generic static function foo<T:{function new(s:String):Void;}>(t:T) {
            trace(Type.typeof(t)); // TClass([class String]) / TClass([class Template])
            return new T("foo");
        }
        
        static public function test() {
            var s = foo("foo");
            var t = foo(new haxe.Template("bar"));
            trace(s); // foo
            trace(t); // haxe.Template
        }

Map

  • 説明: Haxe2では、IntStringをキーに使うデータ構造を提供していました。Haxe3ではトップレベルのMapクラスを使うことで、オブジェクトをキーとすることが可能になりました。生成されたコードでは、選んだキーの型により最適化されたデータ構造が自動的に使用されます。
  • :
    // キーは文字列、値はInt
    var map = new Map();
    map.set("foo", 99);
    trace(map.get("foo")); // 99
    
    // キーはInt、値もInt
    var map = new Map();
    map.set(6, 7);
    trace(map.get(6)); // 7
    
    // キーはオブジェクト、値は関数
    var http = new haxe.Http("haxe.org");
    var map = new Map();
    map.set(http, function() return "haxe.org");
    trace(map.get(http)()); // haxe.org

さらに、Mapでは配列の演算子を用いて要素へアクセス可能です。

var map = new Map();
map["foo"] = 9;
trace(map["foo"]); // 9
map["foo"] += 12;
trace(map["foo"]); // 21

マクロの実体化

  • 説明: マクロの実体化はHaxe2からありましたが、いくつかの機能が欠けており多くの手作業が必要でした。しかし、Haxe3で大幅に改善され、文字列内の変数展開に近いものになりました。
  • :
    var e1 = macro 4; //普通の定数4
    var e2 = macro $e1 + 2; // 4 + 2の演算;
    // ここからHaxe3の新機能
    var e3 = macro myFunc($a{[$e1, $e2]}); // 4 と 4 + 2を引数とした関数呼び出し
    var e4 = macro $p{["haxe", "Log", "trace"]}; // haxe.Log.traceのパス。
    var ident = "varName";
    var e5 = macro trace($i{ident}); // 識別子identを引数にしてvarNameをtrace
    var e6 = macro $b{[e1,e2,e3,e4,e5]}; // 上記全てをブロックにする。

パターンマッチング

  • 説明: Haxeの列挙型(enum)は強力な抽象データ構造ですが、より深い情報についてswitchを行う場合は冗長になりがちでした。Haxe3のパターンマッチングは、列挙型だけでなくその内部の構造や配列に対しても分岐を可能にします。
  • :
    var expr = macro someCall("1");
    switch(expr.expr) {
        case ECall({expr: EConst(CIdent("someCall")) }, [{expr: EConst(arg)}]):
            trace("Some call to: " +arg); // Some call to: CString(1)
        case _:
            trace ("No match");
    }
  • 詳細: パターンマッチング
version #19978, modified 2014-03-05 14:56:28 by shohei909