(2018.7.16. 公開)
Lua/LuaJIT では、関数を自分で定義することができる。関数定義は、下のように記述する。
function 関数名(仮引数リスト)
実行本体
end
「関数名」「仮引数リスト」「実行本体」について、以下でそれぞれ説明する。
関数名は、Lua/LuaJIT で通常用いられる名前である。代入文の左辺と同様、「テーブルフィールド」を使うこともできる。
注意深い人は、「すでに変数として使っている名前を関数名にしたらどうなるのか?」と疑問に思うかもしれない。その答えは、「その変数の中身が捨てられ、新しく定義した関数で置き換えられる」となる。実は、上のように書いた関数定義は、下のような代入文として解釈されるのである。
関数名 = function (仮引数リスト)
実行本体
end
ここで、function (仮引数リスト) 実行本体 end
というのは、「名前のない関数」を定義する構文である。上の代入文は、「関数名
で表される変数に、function (仮引数リスト) 実行本体 end
で定義された「名前のない関数」を代入する」という意味になる。
LÖVE プログラムでよく出てくる次の記述は、何を意味するのだろうか。
function love.load()
x = 0
end
上の説明によれば、この関数定義は、下の代入文と等価である。
love.load = function ()
x = 0
end
つまり、「テーブル love
のフィールド load
に、『x = 0
』を実行本体として持つ関数を代入する」ことを意味している。
LÖVE の処理系は、指定されたディレクトリから main.lua
を読み込んで、その中の関数定義など(上の記述を含む)を実行した後、love.load
を関数として一度だけ実行する。main.lua
を読み込む前は love.load
には「何もしない関数」が入っていたのだが、main.lua
を読み込んで実行した後は、上の記述によって、私たちが書いた love.load
の実行本体と置き換わっている。従って、LÖVE の処理系は私たちの love.load
実行本体を(一度だけ)実行してくれる、という仕組みである。
「仮引数リスト」とは、変数名をコンマ ,
で区切って並べたものである。関数を呼び出す側が与えた引数が、仮引数リストの変数に順に代入される。
仮引数リストの変数は、関数本体のローカル変数となる。つまり、同じ名前の変数がすでに存在している場合、その変数は関数本体の実行が終了するまで隠される。
仮引数リストの変数は0個でもよい。その場合は関数は引数を受け取らない。また、仮引数リストの最後に ...
を置いてもよい。その場合は、余った引数がすべて ...
という式に格納される。この式から引数を取り出すには、select
関数を使うか、{...}
という式でいったんテーブルに変換する。
-- select 関数を使う例
function sample1(v, ...) -- 最初の引数は v, それ以降の引数は ... に入る
local a = select(1, ...) -- v の次の引数
(何か処理を行う)
end
-- テーブルに変換する例
function sample2(v, ...) -- 最初の引数は v, それ以降の引数は ... に入る
local a = {...} -- ... に入った引数からテーブルを作る
(何か処理を行う)
end
関数の実行本体は、文を並べたもの、つまりブロックである。実行途中に return
文に出会うと、関数の実行はそこで終了し、return
文の後に書かれた式の値を戻り値として、呼び出し元に返す。
return
文に出会わずにブロックが終了した場合は、戻り値を持たずに呼び出し元に戻る。
目次