言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Lua辞典

  1. トップページ
  2. Lua辞典
  3. 関数の定義

関数の定義

『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 で複数の値を一度に返せます。関数をテーブルにまとめることでモジュールのような構造を作れます。詳しくは テーブルの基本 も合わせて確認してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。