この第 1 版は Lua 5.0 向けに書かれました。後バージョンの大部分は依然としてこの版に関連がありますが、違いはいくつかあります。
第 4 版は Lua 5.3 を対象としており、Amazon やその他の書店でご購入いただけます。
本を購入することにより、Lua プロジェクトのサポートにもご協力いただけます。
![]() |
Luaでのプログラミング | ![]() |
| 第 1 部言語 第 6 章関数の詳細 |
ファーストクラス関数の明白な結果は、グローバル変数だけでなく、テーブルフィールドとローカル変数に機能を保存できることです。
既に、テーブルフィールドの関数の例をいくつか見てきました。ほとんどの Lua ライブラリはこのメカニズムを使用します(例: io.read、math.sin)。Lua でこのような関数を作成するには、関数とテーブルの通常の構文をまとめるだけで十分です
Lib = {}
Lib.foo = function (x,y) return x + y end
Lib.goo = function (x,y) return x - y end
もちろん、コンストラクターも使用できます Lib = {
foo = function (x,y) return x + y end,
goo = function (x,y) return x - y end
}
さらに、Lua はこれらの関数を定義するための他の構文も提供しています Lib = {}
function Lib.foo (x,y)
return x + y
end
function Lib.goo (x,y)
return x - y
end
この最後のフラグメントは、最初の例とまったく同じです。関数をローカル変数に保存すると、ローカル関数、つまり、特定のスコープに限定された関数になります。このような定義は特にパッケージに役立ちます。Lua は各チャンクを関数として処理するため、チャンクはチャンクの内部からしか見えないローカル関数を宣言できます。字句スコープにより、パッケージ内の他の関数がこれらのローカル関数を使用できるようになります
local f = function (...)
...
end
local g = function (...)
...
f() -- external local `f' is visible here
...
end
Lua はこれらのローカル関数の使用を、シンタックスシュガーでサポートしています local function f (...)
...
end
再帰ローカル関数の定義において、微妙な問題が発生します。ナイーブなアプローチはここで機能しません
local fact = function (n)
if n == 0 then return 1
else return n*fact(n-1) -- buggy
end
end
Lua が関数本体でコール fact(n-1) をコンパイルすると、ローカルの fact はまだ定義されていません。したがって、その表現はローカルの fact ではなく、グローバルの fact をコールします。この問題を解決するには、まずローカル変数を定義してから関数を定義する必要があります local fact
fact = function (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
これで関数の fact はローカル変数を参照します。関数が定義されたときのその値は関係ありません。関数が実行されたときまでに、fact は既に正しい値を持っています。これは Lua がローカル関数用のシンタックスシュガーを展開する方法なので、再帰関数でも気にせず使用できます local function fact (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
もちろん、間接再帰関数を使用する場合、この手法は機能しません。このような場合は、明示的な先読み宣言と同等のものを使用する必要があります local f, g -- `forward' declarations
function g ()
... f() ...
end
function f ()
... g() ...
end
| 著作権 © 2003–2004 Roberto Ierusalimschy. 無断複写・転載を禁じます。 | ![]() |