Множественные возвраты и varargs
Изучаем две яркие особенности Lua: возврат нескольких значений и приём любого числа аргументов.
Множественный возврат — способность функции Lua вернуть сразу несколько значений, перечислив их через запятую после
return.
В большинстве языков функция возвращает одно значение. Lua — приятное исключение: она умеет возвращать несколько и принимать сколько угодно аргументов.
Возврат нескольких значений
local function minmax(a, b)
if a < b then
return a, b -- сначала меньшее, потом большее
else
return b, a
end
end
local lo, hi = minmax(8, 3)
print("min:", lo, "max:", hi)Вывод:
min: 3 max: 8
Множественный возврат повсюду в стандартной библиотеке: string.find возвращает начало и конец совпадения, pcall — успех и результат.
Лишние и недостающие значения
Если переменных меньше, чем возвращённых значений — лишние отбрасываются. Если больше — недостающие становятся nil:
local function three() return 1, 2, 3 end
local a = three() -- берём только первое
local x, y, z, w = three()
print(a)
print(x, y, z, w)Вывод:
1 1 2 3 nil
Переменное число аргументов (varargs)
Многоточие ... в параметрах означает «любое число аргументов»:
local function sum(...)
local total = 0
for _, n in ipairs({...}) do
total = total + n
end
return total
end
print(sum(1, 2, 3))
print(sum(10, 20, 30, 40))Вывод:
6 100
Внутри функции {...} собирает все аргументы в таблицу, по которой удобно пройтись циклом.
Функция select
Узнать число переданных аргументов помогает select("#", ...):
local function countArgs(...)
return select("#", ...)
end
print(countArgs("a", "b", "c"))Вывод:
3
Как работает под капотом
Множественные значения в Lua «разворачиваются» только в конце списка. Поэтому print(three(), 99) напечатает только 1 99: в середине списка от множественного возврата берётся лишь первое значение, а все три значения раскрылись бы только если вызов стоит последним.
Частые ошибки
- Ставить вызов с множественным возвратом в середину списка аргументов — там останется лишь первое значение.
- Использовать
#{...}для подсчёта аргументов, когда среди них естьnil— лучшеselect("#", ...). - Забывать, что лишние возвращённые значения молча отбрасываются.
Итог
- Функция Lua может вернуть несколько значений:
return a, b, c. - Лишние значения отбрасываются, недостающие становятся
nil. - Параметр
...принимает любое число аргументов;{...}собирает их в таблицу. select("#", ...)возвращает точное число аргументов.