0Pricing
Lua Academy · レッスン

関数の定義と呼び出し

関数宣言の構文、呼び出し規約、ローカル関数とグローバル関数の違いを学びます。

「関数の定義と呼び出し」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

関数の構文

Luaでは、functionキーワードを使って関数を定義します。本体はendで終了するブロックです。関数はグローバルにもローカルにもできます。引数を付けた括弧を続けて記述すると、関数を呼び出せます。引数を省略すると、対応するパラメーターにはnilが渡されます。

function sayHello(name)
  print("Hello, " .. (name or "World") .. "!")
end

sayHello("Lua")   -- Hello, Lua!
sayHello()        -- Hello, World!

local function add(a, b)
  return a + b
end
print(add(3, 4))  -- 7

戻り値

関数はreturnを使って値を返します。多くの言語とは異なり、Luaの関数は複数の値を返せます。明示的にreturnしない場合、関数は何も返しません(0個の値)。呼び出しがリスト内の最後の式でない場合、余分な戻り値は破棄されます。

local function minMax(t)
  local lo, hi = t[1], t[1]
  for i = 2, #t do
    if t[i] < lo then lo = t[i] end
    if t[i] > hi then hi = t[i] end
  end
  return lo, hi
end

local lo, hi = minMax({5,2,8,1,9})
print(lo, hi)  -- 1  9

値としての関数

Luaでは、関数は第一級の値です。変数に格納したり、他の関数の引数として渡したり、関数から返したりできます。これにより、コールバック、高階関数、関数型プログラミングのパターンを利用できます。

local ops = {
  add = function(a, b) return a + b end,
  sub = function(a, b) return a - b end,
  mul = function(a, b) return a * b end,
}

local function apply(op, a, b)
  return op(a, b)
end

print(apply(ops.add, 10, 3))  -- 13
print(apply(ops.mul, 4, 5))   -- 20

ローカル関数とグローバル関数

モジュール内部だけで使うヘルパーにはlocal functionを使います。グローバル関数はグローバル名前空間を汚染し、どこからでもアクセスできるため、名前の衝突を引き起こす可能性があります。ほとんどの場合はローカル関数を優先し、必要なものだけをモジュールテーブルを通して公開してください。

-- Bad: pollutes global namespace
function helper() end

-- Good: module-local
local function helper()
  return "I am local"
end

-- Module export pattern
local M = {}
function M.publicFunc()
  return helper()  -- can call local
end
return M

コロン構文によるメソッド

Luaには、テーブルのメソッドを定義および呼び出しするための構文糖があります。obj:method(arg)はobj.method(obj, arg)と同等です。コロン形式では、テーブルが慣例的にselfと名付けられる第1引数として暗黙的に渡されます。

local Dog = {}
Dog.__index = Dog

function Dog.new(name)
  return setmetatable({name=name}, Dog)
end

function Dog:speak()
  print(self.name .. " says: Woof!")
end

local d = Dog.new("Rex")
d:speak()   -- Rex says: Woof!

オプションパラメーターのパターン

Luaには組み込みのオプションパラメーターはありませんが、nilチェックで再現できます。オプションパラメーターが多い関数には、1つのoptionsテーブルを渡してください。長い引数リストよりもすっきりします。

local function createUser(name, opts)
  opts = opts or {}
  return {
    name = name,
    role = opts.role or "user",
    active = opts.active ~= false,
    score = opts.score or 0,
  }
end

local u = createUser("Alice", {role="admin", score=100})
print(u.name, u.role, u.score)

末尾呼び出し

末尾呼び出しとは、末尾位置(returnの前に行う最後の処理)にある関数呼び出しです。Luaは末尾呼び出し最適化を行うため、適切な末尾呼び出しでは追加のスタック領域を使用しません。再帰呼び出しが末尾位置にあれば、スタックオーバーフローを起こさずに深い再帰を実行できます。

local function factorial(n, acc)
  acc = acc or 1
  if n <= 1 then return acc end
  return factorial(n - 1, n * acc)  -- tail call!
end

print(factorial(10))  -- 3628800
-- Can handle very large n without stack overflow

即時実行関数

関数を定義してすぐに呼び出すことができます。(function() ... end)()のように記述します。ローカルスコープを作成したり、セットアップコードを1回だけ実行したり、一時変数で外側のスコープを汚染しないようにしたりする場合に便利です。

local result = (function()
  local temp = 100
  local adjusted = temp * 1.5
  return math.floor(adjusted)
end)()

print(result)   -- 150
-- temp and adjusted not visible here

テーブルへの関数の格納

テーブルに関数を格納する方法は、Luaのモジュール設計でよく使われる慣用的な手法です。テーブルが名前空間として機能します。テーブルのフィールドに関数を代入するか、テーブル名を使ったドット構文やコロン構文で関数を定義します。

local math2 = {}

function math2.clamp(val, lo, hi)
  return math.max(lo, math.min(hi, val))
end

function math2.lerp(a, b, t)
  return a + (b - a) * t
end

print(math2.clamp(150, 0, 100))  -- 100
print(math2.lerp(0, 10, 0.5))   -- 5.0

コールバックとしてのクロージャ

高階関数はコールバックを受け取ります。Luaでは、コールバックは単なる関数の値です。クロージャは呼び出し元のコンテキストをキャプチャするため、追加の引数を高階関数に渡す必要がなく、コールバックとして特に便利です。

local function forEach(t, fn)
  for i, v in ipairs(t) do
    fn(v, i)
  end
end

local sum = 0
forEach({10, 20, 30}, function(v)
  sum = sum + v
end)
print(sum)   -- 60

forEach({"a","b","c"}, function(v, i)
  print(i, v)
end)

クイックチェック

local function f() return 1, 2, 3 end; local a, b = f()の出力は何ですか?

復習:関数

重要なポイント:

  • グローバルを汚染しないように local function を使用します
  • 関数は第一級値です。変数やテーブルに格納したり、引数として渡したりできます
  • コロン構文では self が暗黙的に渡されます
  • opts or {} を使ってオプション引数を再現します
  • 末尾呼び出しにより、深い再帰でのスタックオーバーフローを防げます
  • 即時呼び出し関数によって分離されたスコープを作成できます

よくある質問

「関数の定義と呼び出し」レッスンは無料ですか?

はい。「関数の定義と呼び出し」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「関数の定義と呼び出し」で何を学びますか?

関数宣言の構文、呼び出し規約、ローカル関数とグローバル関数の違いを学びます。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「関数の定義と呼び出し」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 関数の定義と呼び出し
  2. 複数の戻り値
  3. 可変長引数と...演算子
  4. Luaの再帰
← Lua Academyに戻る