0Pricing
Lua Academy · Урок

Переменное число аргументов и оператор ...

Обрабатывайте списки аргументов переменной длины с помощью ... и select().

«Переменное число аргументов и оператор ...» — бесплатный урок Lua Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.

Переменное число аргументов

Функция Lua может принимать переменное число аргументов с помощью ... (трёх точек) в списке параметров. Внутри функции ... обозначает дополнительные аргументы. Их можно использовать в выражениях, передавать другим функциям или преобразовывать в таблицу.

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). Вместе эти функции дают полный контроль над списками аргументов переменной длины.

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(...) — преобразует переменные аргументы в таблицу со счётчиком .n
  • table.unpack(t) — преобразует таблицу в переменные аргументы
  • ... на последнем месте полностью разворачивается, а в средней позиции даёт одно значение

Часто задаваемые вопросы

Урок «Переменное число аргументов и оператор ...» бесплатный?

Да — полный текст урока «Переменное число аргументов и оператор ...» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.

Чему я научусь в уроке «Переменное число аргументов и оператор ...»?

Обрабатывайте списки аргументов переменной длины с помощью ... и select(). Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Lua Academy?

Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Переменное число аргументов и оператор ...»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Lua Academy?

Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Определение и вызов функций
  2. Несколько возвращаемых значений
  3. Переменное число аргументов и оператор ...
  4. Рекурсия в Lua
← Назад к Lua Academy