Переменное число аргументов и оператор ...
Обрабатывайте списки аргументов переменной длины с помощью ... и 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)) -- 100select() для переменного числа аргументов
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). Вместе эти функции дают полный контроль над списками аргументов переменной длины.
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("#", ...)— безопасно подсчитывает аргументы, включая nilselect(n, ...)— возвращает значения, начиная с позиции ntable.pack(...)— преобразует переменные аргументы в таблицу со счётчиком .ntable.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 — локальная установка не требуется.
Все уроки этого курса
- Определение и вызов функций
- Несколько возвращаемых значений
- Переменное число аргументов и оператор ...
- Рекурсия в Lua