【Lua】Luaの基礎文法メモ

Luaの基礎文法超ざっくりメモ。自分用です。随時追加。

Luaの特徴

  • 変数が型を持たない動的型付け言語
  • すべての値は変数に格納できる
  • すべての値は関数の引数、戻り値にできる
  • 初期化していない変数の値はnilとなる
  • 条件判定はnilかfalseだったらときに偽となる

Luaの型

Luaは以下の型を持つ。

  • nil
  • boolean: ブーリアン
  • number: 数値
  • string: 文字列
  • function: 関数
  • table: テーブル
  • thread: スレッド
  • userdata: ユーザデータ

このうち関数、テーブル、スレッド、ユーザデータはオブジェクトと呼ばれ、変数にはその参照が格納される。

変数とスコープ

変数は以下のように宣言する。

-- グローバル変数
foo = "Foo"

-- ローカル変数
local bar = "Bar"

グローバル変数Lua環境テーブルという特殊な場所に格納され、どこからでも参照できる。

ローカル変数は制御構文や関数の中で宣言することでスコープを絞れる。

function add(a, b)
    -- 関数内だけ有効
    local temp = a
    return temp + b
end

またdoとendで囲むことで明示的に「ブロック」を定義するとその内部がローカル変数のスコープとなる。

do
    -- このブロック内でだけ有効
    local temp = 1
end

処理速度とメモリの観点からできるだけローカル変数を使うべき。

テーブル

テーブルは次のように定義する。

t = {} 
配列のように使う

テーブルは配列のように使える。

t = {}
-- 配列のように使用
-- インデックスは1から
t[1] = "aa"
t[2] = 123

以下のようにまとめて書くこともできる。

t = {
    "aa", 
    123
}
連想配列のように使う

テーブルは連想配列のようにも使える。

t = {}
t["key1"] = 123
t["key2"] = "test" 

以下のように書いてもOK

t = {
    key1 = 123,
    key2 = "test"
}
クラスのように使う

テーブルにはの要素にはどんな型でも格納できるため、以下のようにクラスのように使うことができる。

vec3 = {
    x = 0,
    y = 0,
    z = 0,
    Length = function(self)
        return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
    end
}

vec3["x"] = 1
vec3["y"] = 2
vec3["z"] = 3
length = vec3:Length()

以下のようにすればコンストラクタ的なものも定義できる。

vec3 = {}
vec3.new = function(x, y, z)
    local obj = {
        x = x,
        y = y,
        z = z,
        Length = function(self)
            return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
        end
    }
    return obj
end

vec3_1 = vec3.new(1,2,3)
length_1 = vec3_1:Length()

制御構文

if文
foo = 123
if foo >= 100 then
    print("A")
else
    print("B")
end
while文
i = 0
while i < 10 do
    print (i)
    i = i + 1
end
for文
-- 開始値, 終了値, 増加量
for i = 0, 9, 1 do
    print(i)
end
repeat文
i = 0
repeat
    print (i)
    i = i + 1
until (i >= 10)

関数

関数は以下のように扱う。

-- 関数の定義
function add(a, b)
    return a + b
end

-- 呼び出し
result = add(1, 3)

複数の戻り値を返すことも可能。

function func()
    return 123, "abc"
end

a, b = func()
print(a)
print(b)

前述の通りLuaではすべての値は変数に格納できる。
関数も以下のように格納可能。

function func()
    return 123
end

-- 変数に関数を格納
fooFunc = func

print(fooFunc())

コルーチン

コルーチンは以下のようにして使う。

-- コルーチンを作成
local testRoutine = coroutine.create(
    function(initVal)
        coroutine.yield(initVal)
        coroutine.yield(1)
    end
)

-- コルーチンを実行、yieldされるところまで処理が進む
local status1, value1 = coroutine.resume(testRoutine, 123) -- 第二引数で初期値を渡せる
print(value1) -- 123
print(coroutine.status(testRoutine)) -- suspended

-- 次のyieldまでコルーチンを実行
local status2, value2 = coroutine.resume(testRoutine)
print(value2) -- 1
print(coroutine.status(testRoutine)) -- suspended

-- コルーチンが終了したらstatusがdeadになる
local status3, value3 = coroutine.resume(testRoutine)
print(value3) -- nil
print(coroutine.status(testRoutine)) -- dead

以下のようにcoroutine.wrapを使う方法もある。

function func()
    coroutine.yield "1"
    coroutine.yield "2"
    return "end"
end

-- 関数からコルーチンを作成
local co = coroutine.wrap(func)

-- 呼び出し
print(co())
print(co())
print(co())

コメント

-- 一行コメント
--[[
複数行コメント
複数行コメント
]]

エラー

エラーを発生させるためにはerror関数を使う。

error("error")