LÖVE (Love2D) LuaJIT言語編:5.文

(2018.7.14. 公開)

 Lua/LuaJIT のプログラムは、「文」を並べたものである。「文」には以下の種類がある。

 また、ひとつ以上の文を並べたものを「ブロック」と呼ぶ。

 それぞれの文の末尾には、セミコロン ; を置いてもよい(置かなくてもよい)。

5-1. 代入

 代入文は、= の左辺に変数、右辺に式を置いたものである。Lua/LuaJIT では「多重代入」が可能である。すなわち、変数をコンマで区切って複数書くことができ、式も同様に複数書くことができる。

  a = 3           -- a に 3 を代入
  a, b = 2, "xyz" -- a に 2 を、b に "xyz" を代入
  x, y = y, x     -- x と y を交換

 変数の数が式の数より多い時は、足りない値が nil で補われる。逆に、変数の数が式の数より少ない時は、余分な値は捨てられる。

 「変数」の項で説明した通り、「テーブルフィールド」も変数と同様に、代入文の左辺に置くことができる。

  a[i] = i * 2             -- a[i] に i * 2 を代入
  a[i], a[j] = a[j], a[i]  -- a[i] と a[j] を交換

5-2. 条件分岐(if 文)

 if 文は、「ある条件が成立する時だけブロックを実行する」ものである。下のように記述する。

  if 条件1 then
    ブロック1         -- 条件1 が成立した時実行
  elseif 条件2 then   -- 「elseif ... ブロック2」は0回以上繰り返し
    ブロック2         -- 条件1 が成立せず、かつ条件2 が成立した時実行
  else                -- 「else ... ブロックN」は省略可能
    ブロックN         -- どの条件も成立しなかった時実行
  end                 --  end は必ず必要!

 条件1, 条件2 などは、式で記述する。式の値が false または nil であれば、条件は「成立していない」とみなされる。式の値がそれ以外であれば、条件は「成立している」とみなされる。

 if 文を書く時、上のように改行を入れると見やすくなるが、構文規則上は、改行を入れる必要はない。特に、「ブロック1」が一文で、else 部がない時などは、下のように一行で書くこともよくある。end を忘れないように。

  if 条件1 then 文1 end

5-3. while

 while 文は、「ある条件が成立する間はブロックを繰り返し実行する」ものである。下のように記述する。

  while 条件 do  -- do を忘れないように
    ブロック
  end

 条件 は、if 文の場合と同じく、式で記述する。判定も同じで、値が nil または false ならば条件は不成立とみなされ、それ以外の値なら成立とみなされる。

 なお、while 文で、最初から条件が成立していない時は、ブロックは一度も実行されない。

5-4. repeat

 repeat 文は、「ある条件が成立するまでブロックを繰り返し実行する」ものである。下のように記述する。

  repeat  -- do は要らない
    ブロック
  until 条件

 条件 は、if 文の場合と同じく、式で記述する。判定も同じで、値が nil または false ならば条件は不成立とみなされ、それ以外の値なら成立とみなされる。

 repeat 文は、while 文とは違って、ブロックは必ず一度は実行される。繰り返すかどうかの判定を、ブロックの実行後に行うためである。

5-5. for

 for 文は、指定した変数(ループ変数)をある規則に従って変化させながら、ブロックを繰り返し実行するものである。for 文には、「数値型 for 文」と「一般型 for 文」の2種類がある。

 数値型 for 文は、下のように記述する。

  for 変数 = 式1, 式2, 式3 do  -- 「, 式3」は省略可能。do は省略不可
    ブロック
  end

 この for 文は、次のように実行される。

  1. 式1, 式2, 式3(あれば)を計算する。これらは数値でなくてはならない。式3 が省略されている場合は、1 と見なされる。
  2. 変数 が新しく作られ、それに 式1 の値を代入する。
  3. 変数 の値を 式2の値 と比較し、実行を続けるかを判定する。式3の値 が正の時は、変数 <= 式2の値 であれば実行を続ける。式3の値 が正でない時は、変数 >= 式2の値 であれば実行を続ける。
  4. 実行を続ける場合は、ブロックを実行する。その後、変数式3の値 を加えて、3. に戻る。
  5. 実行を続けない場合は、for 文は終了する。

 次の例は、1 から 10 までの数値を表示する。

  for i = 1, 10 do
    print(i)
  end

 ループ変数は、for 文の開始時に新しく作られ、for 文が終了すると消えてしまう。従って、for 文が終了したあとにループ変数の値を使いたい時は、ブロックの中で別の変数に代入しておく必要がある。

 一般型 for 文は、下のように記述する。

  for 変数リスト in 関数, 式1, 式2 do -- 「, 式2」は省略可能
    ブロック
  end

 変数リスト は、ループ変数のリストを表し、1つの変数、またはいくつかの変数をコンマ , で区切って並べたものである。この for 文は、次のように実行される。

  1. 関数, 式1, 式2(省略されていれば nil)を求める。
  2. 式1, 式2 を引数として 関数 を呼び出し、結果を 変数リスト に代入する。
  3. 一番目のループ変数の値が nil でなければ、ブロックを実行する。その後、2. に戻る。ただし、式2 の値は、一番目のループ変数の値で置き換えられる。
  4. 一番目のループ変数の値が nil ならば、for 文を終了する。

 次の例は、テーブルに格納されているすべてのキーと値を並べて表示するものである。pairs(table) は組み込み関数で、「テーブル中の『次のキーと値』を返す関数(実は組み込み関数の next)」、table を2つの値として返す。

  for k, v in pairs(table) do
    print(k, v)
  end

5-6. 関数呼び出し文

 関数呼び出し文は、関数呼び出し式をそのまま書いたものである。関数の戻り値はすべて捨てられる。

5-7. ローカル変数の宣言

 「ローカル変数」とは、ブロックの中でのみ有効な変数である。ローカル変数は、local 文を用いて宣言する。

  local 変数リスト = 式リスト
  local 変数リスト  -- 式を省略してもよい

 変数リスト は変数名をコンマ , で区切って並べたもの、式リスト は式をコンマで区切って並べたものである。もちろん、変数1つ、式1つでもよい。式の値の数が変数の数よりも多い場合・少ない場合は、多重代入と同様に処理される。

 local 文で宣言されたローカル変数は、local 文の次の文から有効になり、そのブロックが終わると無効になる。

 ローカル変数と同じ名前の変数がすでに存在する場合がある。その変数は、ブロックの外で以前に宣言されたローカル変数かもしれないし、または local 宣言なしに定義された変数(グローバル変数)かもしれない。どちらにしても、その変数は、ローカル変数が有効な間は隠され、ローカル変数が無効になったら元の値が復活する。

  a = 1               -- グローバル変数
  for i = 1, 10 do
    local a = 3       -- ローカル変数(グローバル変数の a は隠される)
    print(a)          -- 3 が表示される
  end
  print(a)            -- 1 が表示される(グローバル変数の a が復活)

5-8. goto 文とラベル文

 Lua (5.2 以降), LuaJIT (2.0 以降) では、goto 文を使って、指定された「ラベル」の位置に移動することができる。ラベル文は、任意の名前の前後にコロン : を2つずつ書いたものである。

  ::ラベル::    -- ラベルは任意の名前
  goto ラベル   -- goto 文のラベルにはコロンはつけない

 goto 文で移動できない場合がある。ラベルが別の関数(関数定義については後述)の内側にあるときと、ラベルを含むブロックで goto 文の位置では見えないローカル変数が宣言されているときである。

5-9. break 文と return

 break 文は、ループから強制的に脱出するものである。break 文が実行されると、その文を含む最も内側の while 文、repeat 文、for 文から脱出して、その次の文へと移動する。

  for i = 1, 10 do
    print(i)
    if i == 5 then break end  -- i が 5 になったらループから脱出
  end
  print("ループ終了")

 return 文は、関数本体から値を返すためのものである。自分で定義した関数(後述)の本体を実行中に return 文に出会うと、return のあとに書かれた式を計算して、その値を戻り値として関数本体の実行を終了する。式は複数あってもよい。

 break 文、return 文は、ブロックの最後の文でなくてはならない。ときどき、プログラム作成中に「仮の処理」として、ブロックの途中で break 文や return 文を書きたくなることがある。その時は、do break end あるいは do return 式 end と書けばよい。doend で囲まれた部分は一つのブロックとみなされるため、上のように書けば break 文・return 文が「ブロックの最後の文」になるためである。

目次