構文

Haxe ではすべての式が同じレベルです。つまり、式を再帰的に入れ子にできます。例えば foo(if (x == 3) 5 else 8) と書けます。この例のように、すべての表現は、一定の の値を 戻り値 とします。

リテラル(定数値)


コード中に以下のように数値、文字列、ブール値、null値、正規表現を記述できます :
    //整数
    0;      // Int
    -134;   // Int
    0xFF00; // Int(16進表記)

    //浮動小数点数
    123.0;  // Float
    .14179; // Float
    13e50;  // Float
    -1e-99; // Float
    
    //文字列
    "hello";             // String
    "hello \"world\" !"; // String
    'hello "world" !';   // String

    //真偽値
    true;  // Bool
    false; // Bool

    //null値
    null; // Unknown<0>

    //正規表現
    ~/[a-z]+/i; // EReg

null は特別な値で、どんな型としても使用可能であり、Dynamic とも異なる挙動を持ちます。詳しくは、型推論で説明します。

演算子

以下の演算子が使用可能です(演算されるのが遅い順):

  • v = e:
    e の値を v に代入し、式全体は e を返します。
  • += -= *= /= %= &= |= ^= <<= >>= >>>= :
    相当する演算の後、代入します。
  • e1 || e2 :
    もし e1true なら true を返し、そうでなければ e2 を評価して返します。e1e2 とも Bool でなくてはなりません。
  • e1 && e2 :
    もし e1false なら false を返し、そうでなければ e2 を評価して返します。e1e2 ともに Bool でなくてはなりません。
  • e1...e2 :
    整数の反復子(イテレータ)を作ります(詳しくは反復子(Iterator)を参照)。
  • == != > < >= <= :
    同じ型の2つの式の間で、通常または物理的な比較を行います。戻り値の型は Bool です。
  • | & ^ :
    2つの Int の式の間で、ビット単位演算を行います。戻り値は Int です。
  • << >> >>> :
    2つの Int の式の間で、ビット単位シフトを行います。戻り値は Int です。
  • e1 + e2 :
    2つの式の間で、たし算をします。戻り値の型は、もし e1e2 両方とも Int の式なら IntIntFloat の式なら Float、その他の場合は String です。
  • e1 - e2 :
    Int または Float の2つの式の間で、ひき算をします。戻り値の型は、もし e1e2 両方とも Int なら Int で、その他の場合は Float です。
  • e1 * e2 :
    かけ算をして、引き算と同様の型の戻り値を返します。
  • e1 / e2 :
    わり算をして、戻り値は Float です。
  • e1 % e2 :
    剰余(余り)を求め、引き算と同様の型の戻り値を返します。

単項演算子

以下の単項演算子が使用可能です :

  • ! :
    ブール値の 否定 です。Bool 値を逆にします。
  • - :
    負の数です。IntFloat 値の符号を変えます。
  • ++ -- :
    式に前置または後置します。前置した場合は、先にインクリメントし、インクリメント後の値を返します。後置した場合は、インクリメント前の値を返してから、インクリメントします。Int または Float 値でのみ使用できます。
  • ~ :
    Int での1の補数です。ビット単位 NOT を行います。

注意 : ~ は常に 32 ビットの整数で用いられます。従って、Neko での 31 ビットの整数では期待される結果をもたらしません。

丸括弧

演算子の実行の際に、特に優先順位をつけるためには、丸括弧で式をくくります。(e)の型と値は eと同じになります。

ブロック

ブロック内では複数の式を処理できます。ブロックの構文は次の通りです :

    {
        e1;
        e2;
        // ...
        eX;
    }

ブロックは、そのブロック内の最後の式の値を返します。

例:

    { f(); x = 124; true; }

このブロックは Bool 型で、true と評価されます。

但し、例外として、空のブロックである{ }Void 型と評価されます。

ローカル変数

ローカル変数(局所変数)は、以下の例のように、ブロック内で var を用いて宣言されます :

    {
        var x;
        var y = 3;
        var z : String;
        var w : String = "";
        var a, b : Bool, c : Int = 0;
    }

変数は、任意で型と初期値を添えて宣言できます。値が与えられない場合、変数の値はデフォルトで null となります。型が与えられていない場合は Unknown 型となりますが、その場合でも、厳密に型が付けられています。詳しくは、型推論で説明しています。

複数のローカル変数を同じ var 式で宣言できます。

ローカル変数は、宣言のなされたブロックが終わるまでの間でのみ定義されます。宣言のされたブロックの外からは、アクセスできません。

識別子

変数の識別子があると、以下の順で 解決 がなされます :

  • ローカル変数の中で最後に宣言されたもの
  • クラスのメンバ(インスタンス)変数(現在のクラスのフィールドと継承されたフィールド)
  • 現在のクラスの静的フィールド(クラス変数)
  • そのファイル中で宣言されたか、インポート された列挙型の構成子
    enum Axis {
        x; // (1)
        y;
        z;
    }

    class C {
        static var x : Int; // (2)
        var x : Int; // (3)

        function new() {
            {
               // ここでの x は(2)のメンバ変数の this.x を意味します
                var x : String; // (4)
                // ここでの x は(4)のローカル変数を意味します
            }
        }

        function f(x : String) { // (5)
            // ここでの x は(5)の関数の引数を意味します
        }

        static function f() {
            // ここでの x は(2)のクラスの静的変数を意味します
        }
    }

    class D {
        function new() {
            // x は (1)の Axis の x を意味します
        }
    }

型の識別子 はインポートされたパッケージに従って解決されます。
詳しくは、パッケージ(package)とインポート(import)を参照してください。

フィールドへのアクセス

オブジェクトのフィールドへのアクセスは、伝統的なドット記法で行われます :

    o.field

関数呼び出し

関数は丸括弧と実引数を区切るカンマを用いて呼び出します。オブジェクトのメソッドへはドット記法でアクセスできます。

    f(1,2,3);
    object.method(1,2,3);

new

予約語 new は、クラスのインスタンスを作る式で用いられます。クラス名は必須で、また引数を取れます :

    a = new Array();
    s = new String("hello");

配列

次のような構文を用いて、値のリストから配列を直接作ることができます :

    var a : Array<Int> = [1,2,3,4];

配列型は格納する要素の型を示す 型パラメータ を持つことに注意してください。このようにすることで、型に関するすべての操作は安全になります。このため、1つの配列に格納する要素は、すべて同じ型でなくてはなりません。

配列の値を読み書きするには、次のように伝統的な角括弧記法を用います :

    first = a[0];
    a[1] = value;

配列の添字は、Int型でなくてはなりません。

条件分岐(if)

if 式の例を挙げます :

    if (life == 0) destroy();
    if (flag) 1 else 2;

if 式の一般的な構文は次のとおりです :

    if( 条件式 ) 式-1 [else 式-2]

はじめに 条件式 が評価されます。これは Bool 型でなくてはなりません。そして true であるなら 式-1 が評価され、そうでなければ、式-2 があれば、それが代わりに評価されます。

もし else がなくて、if の表現が false ならば、式全体の型は Void となります。else がある場合には、式-1式-2 は同じ型でなければならず、その型が if 式の型となります :

    var x : Void = if( flag ) destroy();
    var y : Int = if( flag ) 1 else 2;

Haxe での if は、c言語での三項演算子 a?b:c の構文に似ています。

例外として、もし(ブロックの途中でのように)if ブロックが何も値を返さないと想定されている場合は、式-1式-2 は異なる型であることが許され、if ブロックの型は Void となります。

ループ(while)

while は前置条件または後置条件を用いる標準的なループです :

    while( 条件式 ) ループ式;
    do ループ式 while( 条件式 );

例えば、次のようになります :

    var i = 0;
    while( i < 10 ) {
        // ...
        i++;
    }

または do...while を使って :

    var i = 0;
    do {
        // ...
        i++;
    } while( i < 10 );

if と同じように、while ループの 条件式Bool 型でなくてはなりません。

もうひとつの実用的な例に、10 から 1 にカウントダウンするループがあります :

    var i = 10;
    while( i > 0 ) {
    .......
    i--;
    }

繰り返し(for)

for のループは、伝統的なc言語の for ループと少し異なります。for は事実上、反復子(イテレータ) のために使わます。これについては、この文書中で後で紹介します。for ループの例です :

    for( i in 0...a.length ) {
        foo(a[i]);
    }

戻り値(return)

関数の終わりより前に関数から抜け出したり、関数から値を返す場合には、return 式を用います :

    function odd( x : Int ) : Bool {
        if( x % 2 != 0 )
            return true;
        return false;
    }

return 式は、関数が戻り値を必要としない場合、引数なしで使います :

    function foo() : Void {
        // ...
        if( abort )
            return;
        // ....
    }

break と continue

この2つの予約語は、for ループや while ループから早く抜けたり、ループの次の繰り返しに進む際に役立ちます :

    var i = 0;
    while( i < 10 ) {
        if( i == 7 )
            continue; // この繰り返しをスキップします。
            // このブロック内の文はそれ以上処理されず、
            // ''while'' の条件式の評価に戻ります。
        if( flag )
            break; // 繰り返しを早めて終了します。
            // ''while'' のループから抜け出し、ループの
            // 次の文から先に処理は進みます。
    }

例外

例外は、局所的ではないジャンプをする方法です。例外を throw すると、スタック上のどの呼び出し元の関数でも catch できます。

    function foo() {
        // ...
        throw new Error("invalid foo");
    }

    // ...

    try {
        foo();
    } catch( e : Error ) {
        // 例外の処理
    }

異なる型の例外を処理するために、try の後に複数の catch ブロックを置くこともできます。これらは宣言された順に試行されます。Dynamiccatch すると、すべての例外が catch されます。

    try {
        foo();
    } catch( e : String ) {
        // この種類のエラーを処理
    } catch( e : Error ) {
        // 別の種類のエラーを処理
    } catch( e : Dynamic ) {
        // その他すべてのエラーを処理
    }

一連の try 式と catch 式は、( if 式と同じように)値が必要でない場合を除いて、同じ型の戻り値を持たなくてはなりません。

詳しくは例外処理を参照してください。

switch

switch は同じ値に対して複数の if...else if... else if をテストする方法です :

    if( v == 0 )
        e1
    else if( v == foo(1) )
        e2
    else if( v == 65 || v == 90 )
        e3
    else
        e4;

上記のコードは以下の switch による式に書き換え可能です :

    switch( v ) {
    case 0:
        e1;
    case foo(1):
        e2;
    case 65, 90:
        e3;
    default:
        e4;
    }

注意 : 上の例では、1つの case65, 90 となっていますが、これは、2つ(またはそれ以上)のうちいずれかの値 にマッチすることが期待される場合の例で、コンマで列挙を区切ります。

Haxe における switch は、伝統的な switch と異なります。すべての case は別個であり、1つの case の式が処理された後には、switch のブロックから自動的に抜け出ます。このため、switch では break を使うことはできず、また、default の位置は重要ではありません。

いくつかの プラットフォーム においては、switch は定数の値(とくに整数の定数)では、スピード向上のため、最適化される場合があります。

switchenum に対する特殊な用法を持ちます。これについては、列挙型(enum)を参照してください

ローカル関数

ローカル(局所的な)関数は、 予約語 function を用いて宣言しますが、名前を持ちません。 ローカル関数は、定数値の整数や文字列と同じく です :

    var f = function() { /* ... */ };
    f(); // 関数の呼び出し

ローカル関数は、引数、現在のクラスの静的な変数、関数自身より前に宣言されたローカル変数にアクセス可能です :

    var x = 10;
    var add = function(n) { x += n; };
    add(2);
    add(3);
    // この時点で x は 15 になっている

しかし、メソッドの中で宣言されたローカル関数は、this の値にアクセスできません。そのため、me のようなローカル変数を宣言する必要があります :

    class C {

        var x : Int;

        function f() {
            // コンパイル不可
            var add = function(n) { this.x += n; };
        }

        function f2() {
            // コンパイル可
            var me = this;
            var add = function(n) { me.x += n; };
        }
    }

匿名オブジェクト

匿名オブジェクトは、次のように宣言します :

    var o = { age : 26, name : "Tom" };

型推論 のために、匿名オブジェクトも厳密に型付けされます。
詳しくは、構造体(匿名オブジェクト)を参照してください。

«« 基本型 - 型推論 »»

version #19445, modified 2013-06-13 15:56:39 by shohei909