関数定義

関数定義の構文は次のとおりです。

      function ::= function funcbody
      funcbody ::= `(´ [parlist] `)´ block end

次の糖衣構文では、関数定義が単純化されます。

      statement ::= function funcname funcbody
      statement ::= local function Name funcbody
      funcname ::= Name {`.´ Name} [`:´ Name]

次のステートメント

     function f () body end

は、次のように変換されます。

     f = function () body end

次のステートメント

     function t.a.b.c.f () body end

は、次のように変換されます。

     t.a.b.c.f = function () body end

次のステートメント

     local function f () body end

は、次のように変換されます。

     local f; f = function () body end

次のようではありません

     local f = function () body end

(これは、関数の本体に f への参照が含まれている場合にのみ違いが生じます。)

関数定義は、実行可能な式で、その値の型は関数 です。Lua がチャンクをプリコンパイルするとき、 その関数本体もすべてプリコンパイルされます。そして、Lua が関数定義を実行するときは必ず、関数はインスタンス化 (またはクローズ) されます。この関数インスタンス (またはクロージャー) は、式の最終的な値です。同じ関数の異なるインスタンスは、 異なる外部ローカル変数を参照することがあり、異なる環境表を持つことがあります。

パラメーターは、引数値によって初期化されるローカル変数として振る舞います。

      parlist ::= namelist [`,´ `...´] | `...´

関数を呼び出すと、引数リストがパラメーター・リストの長さに調整されます。ただし、パラメーター・リストの最後が 3 つのドット ('...') になっている可変個引数関数または可変引数関数 の場合を除きます。可変引数関数は引数リストを調整しません。代わりに、すべての余分な引数を収集し、それを可変引数式 を介して関数に渡します。可変引数式もまた、3 つのドットで記述されます。この式の値は、すべての余分な実引数のリストで、 複数の結果を持つ関数に似ています。可変引数式が他の式の中や式リストの途中で使用された場合、 その戻りリストは 1 個のエレメントに調節されます。式が、式リストの最後のエレメントとして使用された場合、(最後の式が括弧で囲まれた場合を除いて) 調整は行われません。

例として、次の定義を考えてみます。

     function f(a, b) end
     function g(a, b, ...) end
     function r() return 1,2,3 end

この場合、引数からパラメーターと可変引数式へ、以下のようにマッピングされます。

     CALL            PARAMETERS
     f(3)             a=3, b=null
     f(3, 4)          a=3, b=4
     f(3, 4, 5)       a=3, b=4
     f(r(), 10)       a=1, b=10
     f(r())           a=1, b=2

     g(3)             a=3, b=null, ... -->  (nothing)
     g(3, 4)          a=3, b=4,   ... -->  (nothing)
     g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
     g(5, r())        a=5, b=1,   ... -->  2  3

結果は、return ステートメントを使用して返されます (『制御構造』を参照)。return ステートメントを検出せずに制御が関数の終りに達すると、関数は結果なしで戻ります。