Несколько возвращаемых значений
Возвращайте и сохраняйте несколько значений, полученных в результате одного вызова функции.
«Несколько возвращаемых значений» — бесплатный урок Lua Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Возврат нескольких значений
В отличие от большинства языков, функции Lua могут естественным образом возвращать несколько значений из одного оператора return. Несколько значений указываются после return через запятую. Благодаря этому не нужны обёртки-объекты или выходные параметры.
local function divmod(a, b)
return math.floor(a / b), a % b
end
local quotient, remainder = divmod(17, 5)
print(quotient, remainder) -- 3 2Настройка возвращаемых значений
Lua настраивает возвращаемые значения в соответствии с количеством принимающих переменных. Лишние значения отбрасываются, а отсутствующие становятся равными nil. Такая настройка выполняется, когда вызов функции находится не на последнем месте в списке выражений — в этом случае сохраняется только первое значение.
local function triple()
return 10, 20, 30
end
local a, b, c = triple()
print(a, b, c) -- 10 20 30
local x, y = triple()
print(x, y) -- 10 20 (30 discarded)
local p = triple()
print(p) -- 10 (only first when 1 var)Настройка в средней позиции
Если вызов функции находится в середине списка выражений, а не на последнем месте, Lua сокращает его до одного значения. Только последнее выражение в списке может возвращать несколько значений.
local function pair()
return 1, 2
end
-- pair() in middle: only 1 value used
local t = {pair(), pair()}
print(#t, t[1], t[2], t[3]) -- 3 1 1 2
-- first pair() gives just 1; last pair() gives 1,2
-- pair() at end: all values used
local t2 = {10, pair()}
print(#t2, t2[1], t2[2], t2[3]) -- 3 10 1 2Скобки принудительно оставляют одно значение
Заключение вызова функции в скобки заставляет её вернуть ровно одно значение. Это полезно, когда Вам нужно только первое возвращаемое значение независимо от того, сколько значений создаёт функция.
local function coords()
return 10, 20, 30
end
print(coords()) -- 10 20 30 (all three)
print((coords())) -- 10 (parentheses: single value only)
local x = (coords())
print(x) -- 10Возвращаемые значения string.find
Многие функции стандартной библиотеки возвращают несколько значений. string.find возвращает начальную и конечную позиции совпадения (а также захваченные фрагменты). math.modf возвращает целую и дробную части. Понимание этих закономерностей помогает свободно пользоваться стандартной библиотекой.
local s = "hello world"
local start, finish = string.find(s, "world")
print(start, finish) -- 7 11
-- math.modf: integer and fractional parts
local int, frac = math.modf(3.75)
print(int, frac) -- 3 0.75Сбор значений с помощью table.pack
table.pack(...) собирает все аргументы (или возвращаемые значения через ...) в таблицу. Таблица содержит поле n с общим количеством значений, включая значения nil. Это сохраняет точное количество, в отличие от #, который останавливается на первой пустой позиции.
local function getData()
return "Alice", 30, nil, true
end
local t = table.pack(getData())
print(t.n) -- 4
print(t[1]) -- Alice
print(t[2]) -- 30
print(t[3]) -- nil
print(t[4]) -- truetable.unpack для разворачивания
table.unpack(t, i, j) возвращает элементы таблицы как отдельные значения. Это обратная операция по отношению к table.pack. Используйте её, чтобы передать содержимое таблицы функции в качестве аргументов или развернуть значения в операторе возврата.
local args = {10, 20, 30}
local function sum3(a, b, c)
return a + b + c
end
print(sum3(table.unpack(args))) -- 60
-- Use in return
local function passThrough(t)
return table.unpack(t)
end
print(passThrough({5, 6, 7})) -- 5 6 7Возврат в стиле обработки ошибок
Распространённое соглашение в Lua — возвращать nil, errorMessage при неудаче и результат при успехе. Вызывающий код проверяет первое возвращаемое значение: если это nil, произошла ошибка. Такой подход позволяет не использовать исключения для ожидаемых случаев неудачи.
local function openConfig(path)
local f = io.open(path, "r")
if not f then
return nil, "cannot open: " .. path
end
local content = f:read("*a")
f:close()
return content
end
local data, err = openConfig("config.lua")
if not data then
print("Error:", err)
endОбмен значениями с несколькими возвращаемыми значениями
Несколько возвращаемых значений элегантно решают задачу обмена. Правая часть вычисляется до присваивания, поэтому a, b = b, a корректно меняет значения местами без временной переменной.
local a, b = 5, 10
print(a, b) -- 5 10
a, b = b, a
print(a, b) -- 10 5
-- Works for three-way rotation too
local x, y, z = 1, 2, 3
x, y, z = z, x, y
print(x, y, z) -- 3 1 2Соглашение о возвращаемых значениях pcall
pcall(f, ...) сама использует несколько возвращаемых значений: первое значение — логическое (true при успехе и false при ошибке), а последующие значения — это либо возвращаемые значения f, либо сообщение об ошибке. Всегда проверяйте первое возвращаемое значение, прежде чем использовать остальные.
local function risky(x)
if x < 0 then error("negative input") end
return math.sqrt(x)
end
local ok, result = pcall(risky, 16)
print(ok, result) -- true 4.0
ok, result = pcall(risky, -1)
print(ok, result) -- false input:2: negative inputБыстрая проверка
Что выведет print((string.find("hello", "ll")))?
Повторение: несколько возвращаемых значений
Основные выводы:
- Возвращайте несколько значений:
return a, b, c - Лишние значения отбрасываются, а отсутствующие становятся nil
- Вызовы в средней позиции сокращаются до 1 значения
(f())принудительно оставляет ровно 1 значениеtable.pack/table.unpackиспользуются для динамических списков значений- Соглашение: при неудаче возвращайте
nil, errmsg
Часто задаваемые вопросы
Урок «Несколько возвращаемых значений» бесплатный?
Да — полный текст урока «Несколько возвращаемых значений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Несколько возвращаемых значений»?
Возвращайте и сохраняйте несколько значений, полученных в результате одного вызова функции. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Несколько возвращаемых значений»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Определение и вызов функций
- Несколько возвращаемых значений
- Переменное число аргументов и оператор ...
- Рекурсия в Lua