Haxeと構造的部分型付け


Haxeがサポートしている「構造的部分型付け(Structural Subtyping)」という素晴らしい機能について紹介します。

まずは、サンプルコードを見てください。

Main.hx
class Main {
    static function main() {
        start( new Human() );   //エラーなし
        start( new Car() );     //エラーなし
        start( new Fish() );    //コンパイルエラー!!
    }

    static public function start( runner ) {
        runner.run();   //変数runnerには、run関数が必要。
    }
}

class Human {
    public function new(){}
    public function run() {
        trace( "人は走るよ!" );
    }
}

class Car {
    public function new(){}
    public function run() {
        trace( "車も走るよ!" );
    }
}

class Fish {
    public function new(){}
}

上の例では、start()にHuman、Car、Fishを渡していますが、Fishでのみコンパイルエラーが発生してます。これは、runnerが「run関数を持つ型」として型推論されており、そこにrun関数をもたないFishを渡しために起きたエラーです。

このように、クラスがどのような変数や関数を持ってるかという構造に対して、部分的に型付けできるのが、「構造的部分型付け」です。


さらに、「run関数を持つ型」というのは明示的に宣言することが可能です。
つまり、サンプルコードのstart()は以下のように書きかえることができます。

start()
    static public function start( runner: { function run():Void; } ) {
        runner.run();
    }

さらに詳しい話については、公式ドキュメントの構造体を見てください