関数の定義
『Lua』では function キーワードを使って関数を定義します。グローバル関数・ローカル関数・無名関数・テーブルフィールドへの代入・コロン構文によるメソッド定義など、複数のスタイルがあります。ここでは各定義スタイルと呼び出し方法を確認します。
構文
-- -----------------------------------------------
-- グローバル関数定義(最も基本的な形式)
-- -----------------------------------------------
function 関数名(引数1, 引数2)
-- 処理
return 戻り値 -- return は省略可能(nil を返します)
end
-- -----------------------------------------------
-- ローカル関数定義(スコープを制限する推奨形式)
-- -----------------------------------------------
local function 関数名(引数1, 引数2)
return 戻り値
end
-- -----------------------------------------------
-- 無名関数(変数に代入する形式)
-- -----------------------------------------------
local 変数名 = function(引数1, 引数2)
return 戻り値
end
-- -----------------------------------------------
-- テーブルフィールドへの関数定義
-- -----------------------------------------------
local テーブル名 = {}
テーブル名.関数名 = function(引数)
return 戻り値
end
-- または宣言と同時に定義
local テーブル名 = {
関数名 = function(引数)
return 戻り値
end,
}
-- -----------------------------------------------
-- コロン構文によるメソッド定義(self を暗黙で受け取ります)
-- -----------------------------------------------
function テーブル名:メソッド名(引数)
-- self でテーブル自身を参照できます
return self.フィールド名
end
-- -----------------------------------------------
-- 引数のデフォルト値パターン(Lua に専用構文はありません)
-- -----------------------------------------------
local function 関数名(引数1, 引数2)
引数2 = 引数2 or デフォルト値 -- nil のときにデフォルト値を適用します
return 引数1 + 引数2
end
構文一覧
| 構文/形式 | 概要 |
|---|---|
function 名前(引数) end | グローバルスコープに関数を定義します。ファイル内のどこからでも呼び出せますが、意図しない名前衝突を起こす可能性があります。 |
local function 名前(引数) end | 現在のスコープに限定されたローカル関数を定義します。スコープ外への意図しない影響を防ぐため、多くの場面で使われます。 |
local 名前 = function(引数) end | 無名関数を変数に代入する形式です。関数を値として扱うことができ、コールバックや高階関数によく使います。 |
テーブル.フィールド = function(引数) end | テーブルのフィールドに関数を代入します。モジュールや名前空間のような構造を作るときに使います。 |
function テーブル:メソッド(引数) end | コロン構文でメソッドを定義します。第一引数として self(テーブル自身)が暗黙で渡されます。 |
テーブル:メソッド(引数) | コロン構文でメソッドを呼び出します。self を自動で渡すため、テーブル.メソッド(テーブル, 引数) と等価です。 |
引数 = 引数 or デフォルト値 | 引数のデフォルト値パターンです。Lua には専用構文がないため、or 演算子で nil のときのフォールバック値を設定します。 |
return 値1, 値2 | 複数の値を同時に返します(多値返却)。受け取る側も local a, b = 関数() のように複数の変数で受け取れます。 |
サンプルコード
kof_function_basic.lua
-- kof_function_basic.lua — Lua の関数定義と呼び出しのサンプルです
-- KOF(ザ・キング・オブ・ファイターズ)のキャラクターを使って
-- 各種関数定義スタイルを確認します
-- -----------------------------------------------
-- グローバル関数定義
-- -----------------------------------------------
-- 技名と威力を受け取って文字列を返すグローバル関数です
function announceMove(character, move, power)
return character .. " の「" .. move .. "」! 威力: " .. power
end
print("=== グローバル関数 ===")
print(announceMove("テリー・ボガード", "パワーウェイブ", 80))
print(announceMove("アンディ・ボガード", "昇龍弾", 85))
print("")
-- -----------------------------------------------
-- ローカル関数定義(推奨形式)
-- -----------------------------------------------
-- 戦闘力からランクを返すローカル関数です
local function getRank(power)
if power >= 95 then
return "S ランク"
elseif power >= 85 then
return "A ランク"
elseif power >= 75 then
return "B ランク"
else
return "C ランク"
end
end
print("=== ローカル関数 ===")
print("不知火舞(power: 88)→ " .. getRank(88))
print("ジョー東(power: 82)→ " .. getRank(82))
print("")
-- -----------------------------------------------
-- 無名関数(変数に代入)
-- -----------------------------------------------
-- 勝利メッセージを組み立てる無名関数です
local buildWinMessage = function(winner, loser)
return winner .. " が " .. loser .. " を倒した!"
end
print("=== 無名関数 ===")
print(buildWinMessage("ラルフ・ジョーンズ", "クラーク・スティル"))
print("")
-- -----------------------------------------------
-- テーブルフィールドへの関数定義(モジュール風)
-- -----------------------------------------------
-- ファイター情報を管理するテーブルを定義します
local FighterUtil = {}
FighterUtil.formatProfile = function(name, team, power)
return string.format("名前: %s チーム: %s 戦闘力: %d %s",
name, team, power, getRank(power))
end
print("=== テーブルフィールド関数 ===")
print(FighterUtil.formatProfile("テリー・ボガード", "餓狼伝説チーム", 95))
print(FighterUtil.formatProfile("ラルフ・ジョーンズ", "怒チーム", 93))
print("")
-- -----------------------------------------------
-- コロン構文によるメソッド定義
-- -----------------------------------------------
-- ファイターオブジェクトを定義します
local fighter = {
name = "不知火舞",
team = "餓狼伝説チーム",
power = 88,
hp = 100,
}
-- コロン構文でメソッドを定義します(self でテーブル自身を参照できます)
function fighter:introduce()
return self.name .. "(" .. self.team .. ")です。よろしく!"
end
function fighter:takeDamage(damage)
self.hp = self.hp - damage
return self.name .. " は " .. damage .. " ダメージを受けた。残り HP: " .. self.hp
end
print("=== コロン構文メソッド ===")
print(fighter:introduce())
print(fighter:takeDamage(30))
print(fighter:takeDamage(20))
print("")
-- -----------------------------------------------
-- 引数のデフォルト値パターン
-- -----------------------------------------------
-- 技の威力を計算します。boost が省略されたときは 1.0 をデフォルトにします
local function calcPower(base, boost)
boost = boost or 1.0 -- nil のときにデフォルト値 1.0 を適用します
return math.floor(base * boost)
end
print("=== デフォルト値パターン ===")
print("パワーウェイブ(通常): " .. calcPower(80))
print("パワーウェイブ(強化 1.5x): " .. calcPower(80, 1.5))
print("バーンナックル(強化 2.0x): " .. calcPower(90, 2.0))
print("")
-- -----------------------------------------------
-- 多値返却
-- -----------------------------------------------
-- 勝者と敗者を同時に返します
local function battle(a, aPower, b, bPower)
if aPower >= bPower then
return a, b -- 第一返却値が勝者、第二返却値が敗者です
else
return b, a
end
end
print("=== 多値返却 ===")
local winner, loser = battle("テリー・ボガード", 95, "ジョー東", 82)
print("勝者: " .. winner .. " 敗者: " .. loser)
lua kof_function_basic.lua === グローバル関数 === テリー・ボガード の「パワーウェイブ」! 威力: 80 アンディ・ボガード の「昇龍弾」! 威力: 85 === ローカル関数 === 不知火舞(power: 88)→ A ランク ジョー東(power: 82)→ B ランク === 無名関数 === ラルフ・ジョーンズ が クラーク・スティル を倒した! === テーブルフィールド関数 === 名前: テリー・ボガード チーム: 餓狼伝説チーム 戦闘力: 95 S ランク 名前: ラルフ・ジョーンズ チーム: 怒チーム 戦闘力: 93 A ランク === コロン構文メソッド === 不知火舞(餓狼伝説チーム)です。よろしく! 不知火舞 は 30 ダメージを受けた。残り HP: 70 不知火舞 は 20 ダメージを受けた。残り HP: 50 === デフォルト値パターン === パワーウェイブ(通常): 80 パワーウェイブ(強化 1.5x): 120 バーンナックル(強化 2.0x): 180 === 多値返却 === 勝者: テリー・ボガード 敗者: ジョー東
よくあるミス
よくあるミス1: コロン構文とドット構文を混在させる
コロン構文でメソッドを定義した関数をドット構文で呼ぶと、self が渡されず意図しない動作になります。逆も同様です。
ng_example.lua
local obj = { name = "Kiryu" }
function obj:greet()
return "Hello, I am " .. self.name
end
-- コロン構文で定義したメソッドをドット構文で呼ぶ
print(obj.greet()) -- self が渡されないのでエラー
lua: ng_example.lua:4: attempt to index a nil value (local 'self')
コロン構文で定義したメソッドはコロン構文で呼びます。
ok_example.lua
local obj = { name = "Kiryu" }
function obj:greet()
return "Hello, I am " .. self.name
end
print(obj:greet()) -- コロン構文で呼ぶ
Hello, I am Kiryu
よくあるミス2: arg or default で false が上書きされる
arg = arg or default のパターンは、引数が nil のときだけでなく false のときにもデフォルト値に置き換わります。false を有効な値として扱う引数には使えません。
ng_example2.lua
local function setFlag(value)
value = value or true -- false を渡しても true になってしまう
return value
end
print(setFlag(false)) -- false のつもりが true になる
print(setFlag(nil)) -- nil のときは true になる(期待通り)
true true
false も有効な値として扱う場合は nil チェックを明示します。
ok_example2.lua
local function setFlag(value)
if value == nil then
value = true
end
return value
end
print(setFlag(false)) -- false のまま
print(setFlag(nil)) -- true
false true
概要
Lua の関数は「第一級の値(first-class value)」です。変数に代入したり、テーブルのフィールドに格納したり、他の関数に引数として渡したりできます。定義スタイルは大きく分けて「グローバル関数」「ローカル関数」「無名関数の変数代入」「テーブルフィールド代入」「コロン構文メソッド」の5種類があります。スコープを限定するため、local function または変数への無名関数代入を基本とします。グローバル関数は、ファイルをまたいで参照させたいシンボルを意図的に公開したい場合に使います。コロン構文(function t:method())は self を暗黙の第一引数として受け取るシンタックスシュガーで、オブジェクト指向スタイルのコードを書くときに多用します。引数のデフォルト値には専用構文がなく、arg = arg or default というイディオムを使います。また Lua は多値返却をネイティブにサポートしており、return a, b で複数の値を一度に返せます。関数をテーブルにまとめることでモジュールのような構造を作れます。詳しくは テーブルの基本 も合わせて確認してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。