0Pricing
Lua Academy · レッスン

可変長引数と...演算子

...と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.lua

table.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フィードバックを取得できます。ローカル設定は不要です。

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

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