LÖVE (Love2D) LuaJIT言語編:6.関数定義

(2018.7.16. 公開)

 Lua/LuaJIT では、関数を自分で定義することができる。関数定義は、下のように記述する。

function 関数名(仮引数リスト)
  実行本体
end

 「関数名」「仮引数リスト」「実行本体」について、以下でそれぞれ説明する。

6-1. 関数名

 関数名は、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 実行本体を(一度だけ)実行してくれる、という仕組みである。

6-2. 仮引数リスト

 「仮引数リスト」とは、変数名をコンマ , で区切って並べたものである。関数を呼び出す側が与えた引数が、仮引数リストの変数に順に代入される。

 仮引数リストの変数は、関数本体のローカル変数となる。つまり、同じ名前の変数がすでに存在している場合、その変数は関数本体の実行が終了するまで隠される。

 仮引数リストの変数は0個でもよい。その場合は関数は引数を受け取らない。また、仮引数リストの最後に ... を置いてもよい。その場合は、余った引数がすべて ... という式に格納される。この式から引数を取り出すには、select 関数を使うか、{...} という式でいったんテーブルに変換する。

  --  select 関数を使う例
  function sample1(v, ...)    -- 最初の引数は v, それ以降の引数は ... に入る
    local a = select(1, ...)  -- v の次の引数
    (何か処理を行う)
  end
  --  テーブルに変換する例
  function sample2(v, ...)    -- 最初の引数は v, それ以降の引数は ... に入る
    local a = {...}           -- ... に入った引数からテーブルを作る
    (何か処理を行う)
  end

6-3. 実行本体

 関数の実行本体は、文を並べたもの、つまりブロックである。実行途中に return 文に出会うと、関数の実行はそこで終了し、return 文の後に書かれた式の値を戻り値として、呼び出し元に返す。

 return 文に出会わずにブロックが終了した場合は、戻り値を持たずに呼び出し元に戻る。

目次