可変長引数と...演算子
...とselect()を使って可変長の引数リストを処理します。
「可変長引数と...演算子」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
可変長引数
Luaの関数は、パラメータリストで ...(ドット3つ)を使用すると、可変個数の引数を受け取れます。関数内では、... が追加の引数を表します。式で使用したり、他の関数に渡したり、テーブルに変換したりできます。
local function sum(...)
local total = 0
for _, v in ipairs({...}) do
total = total + v
end
return total
end
print(sum(1, 2, 3)) -- 6
print(sum(10, 20, 30, 40)) -- 100可変長引数に使うselect()
select(n, ...) は、n番目以降の引数を返します。select("#", ...) は、nil値を含む引数の合計数を返します。最初のnilによる空きで停止する #{...} より安全です。
local function inspect(...)
local n = select("#", ...)
print("count:", n)
for i = 1, n do
print(i, select(i, ...))
end
end
inspect("a", "b", nil, "d")
-- count: 4
-- 1 a
-- 2 b
-- 3 nil
-- 4 d別の関数に...を渡す
f(...) を使うと、可変長引数を別の関数に直接転送できます。呼び出しの最後の引数として ... を記述すると、すべての可変長引数が渡されます。関数のラッパーやロギングに便利です。
local function log(level, ...)
io.write("[" .. level .. "] ")
print(...)
end
log("INFO", "Server started on port", 8080)
log("ERROR", "File not found:", "config.lua")
-- [INFO] Server started on port 8080
-- [ERROR] File not found: config.luatable.packとtable.unpack
table.pack(...) を使うと可変長引数をテーブルに変換でき、個数も n フィールドに保存されます。table.unpack(t, i, j) を使うと、テーブルを可変長引数に戻せます。この2つの関数を組み合わせることで、可変長引数リストを完全に制御できます。
local function pack_and_show(...)
local packed = table.pack(...)
print("n =", packed.n)
for i = 1, packed.n do
print(i, packed[i])
end
end
pack_and_show(10, nil, 30)
-- n = 3
-- 1 10
-- 2 nil
-- 3 30固定引数と可変長引数の組み合わせ
関数には、固定パラメータと可変長パラメータの両方を指定できます。固定パラメータを先に記述し、... で残りを受け取ります。固定パラメータへの代入が先に行われ、その後の引数が ... に入ります。
local function printf(fmt, ...)
io.write(string.format(fmt, ...))
end
printf("Hello, %s! You are %d years old.\n", "Alice", 30)
printf("Pi is approximately %.4f\n", math.pi)
local function firstAndRest(first, ...)
print("first:", first)
print("rest count:", select("#", ...))
end
firstAndRest(1, 2, 3, 4)テーブルコンストラクターでの可変長引数
可変長引数は、テーブルコンストラクターに直接展開できます:{...}。最後の要素として使用すると、すべての引数が含まれます。ただし、nilによる空きがあると # の結果が不明確になる場合があります。正確な個数が必要な場合は table.pack を優先してください。
local function toArray(...)
return {...} -- collect all args as array
end
local arr = toArray("x", "y", "z")
for i, v in ipairs(arr) do
print(i, v)
end
-- 1 x
-- 2 y
-- 3 z可変長引数の式
... は任意の式の位置に記述できます。多重代入では、すべての値に展開されます。算術式では、最初の値だけが使用されます。この動作を理解しておくと、... と他の式を組み合わせたときの微妙なバグを防げます。
local function first(...)
local x = ...
return x
end
print(first(10, 20, 30)) -- 10 (only first)
local function addFirst(n, ...)
local x = ...
return n + x
end
print(addFirst(5, 3, 99)) -- 8 (3 is first ...)print()も可変長引数を使用する
Lua組み込みの print() 自体も可変長引数関数です。任意個数の引数を受け取り、それぞれを文字列に変換して、タブで区切って出力します。この仕組みを理解すると、同様のユーティリティ関数を作成するのに役立ちます。
-- print is vararg
print(1, 2, 3) -- 1 2 3
print("a", nil, "b") -- a nil b
print() -- (empty line)
-- Reimplementing a simple print-like function
local function myprint(...)
local parts = {}
for i = 1, select("#", ...) do
parts[i] = tostring(select(i, ...))
end
io.write(table.concat(parts, "\t") .. "\n")
end
myprint(10, nil, 30)pcallによる転送
pcallと可変長引数を組み合わせると、汎用的な安全呼び出しラッパーを作成できます。ラッパーは関数と任意個数の引数を受け取り、pcall経由で関数を呼び出し、結果またはエラーを返します。
local function safeCall(fn, ...)
local ok, result = pcall(fn, ...)
if ok then
return result
else
print("Error:", result)
return nil
end
end
local function divide(a, b)
assert(b ~= 0, "division by zero")
return a / b
end
print(safeCall(divide, 10, 2)) -- 5.0
print(safeCall(divide, 10, 0)) -- Error: ...可変長引数を蓄積するパターン
可変長引数でよく使われるパターンは、すべての引数を反復処理して結果を蓄積する方法です。ローカルテーブルを使うか、select で直接合計できます。どちらも有効ですが、引数が多い場合はテーブルを使う方法のほうが明確です。
local function average(...)
local n = select("#", ...)
if n == 0 then return 0 end
local total = 0
for i = 1, n do
total = total + select(i, ...)
end
return total / n
end
print(average(10, 20, 30, 40)) -- 25.0
print(average(5)) -- 5.0確認問題
select("#", 1, nil, 3) は何を返しますか?
復習:可変長引数
まとめ:
function f(...)— 可変長引数を受け取りますselect("#", ...)— nilを含めて安全に個数を数えますselect(n, ...)— n番目以降の値を取得しますtable.pack(...)— 可変長引数を個数付きのテーブルに変換しますtable.unpack(t)— テーブルを可変長引数に変換します- 最後の位置の
...は完全に展開され、中間位置では1つの値になります
よくある質問
「可変長引数と...演算子」レッスンは無料ですか?
はい。「可変長引数と...演算子」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「可変長引数と...演算子」で何を学びますか?
...とselect()を使って可変長の引数リストを処理します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「可変長引数と...演算子」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 関数の定義と呼び出し
- 複数の戻り値
- 可変長引数と...演算子
- Luaの再帰