Возвращаемые значения
Функции, которые вы написали до сих пор, что-то выводят, и только. Но часто нужно, чтобы функция вычислила значение, с которым программа будет работать дальше: сложит, сравнит или сохранит его. Тогда функция возвращает значение с помощью return:
local function harvestValue(count, price)
return count * price
end
local carrots = harvestValue(12, 5)
print("Морковь, монеты: " .. carrots)
print("Тыквы, монеты: " .. harvestValue(4, 20))Программа выводит:
Морковь, монеты: 60
Тыквы, монеты: 80Вызов harvestValue(12, 5) запускает функцию, а return отправляет 60 обратно на место вызова. Можно представить, что Lua заменяет вызов возвращённым значением, так что local carrots = harvestValue(12, 5) превращается в local carrots = 60. Это значение — возвращаемое значение функции. Вызов можно использовать везде, где можно написать значение: в переменной, в print, в вычислении или в условии, например if harvestValue(12, 5) > 50 then. Такие функции вы уже знаете: math.max(3, 8) возвращает 8, а tostring(5) возвращает "5".
return ещё и сразу завершает функцию. Вместе с условиями это даёт короткие функции, которые в разных случаях возвращают разные значения:
local function sellPrice(crop)
if crop == "морковь" then
return 5
elseif crop == "картофель" then
return 8
end
return 0
end
print(sellPrice("картофель"), sellPrice("морковь"), sellPrice("камень"))Программа выводит:
8 5 0Для "картофель" выполняется второй return, и функция заканчивается: до return 0 Lua не доходит. Он доходит до него, только когда ни одно условие не выполнено. В Lua return должен быть последней строкой своего блока (прямо перед end, else или elseif). Строка после него в том же блоке — синтаксическая ошибка: 'end' expected … near 'print'.
Новички часто путают print и return, ведь оба как будто «выдают» значение. Но print лишь показывает значение вам, в выводе, а программа с ним работать не может. return отдаёт значение программе. Посмотрите на функцию, которая выводит результат вместо того, чтобы вернуть его:
local function harvestValue(count, price)
print(count * price)
end
local carrots = harvestValue(12, 5)
print(carrots)
print(carrots + 10)Программа выводит:
60
nil
main.lua:7: attempt to perform arithmetic on a nil value (local 'carrots')60 выводит print внутри функции. Но функция ничего не вернула, поэтому carrots равно nil, и вычисление завершается ошибкой. Если вы видите nil там, где ожидали результат функции, проверьте, есть ли в функции return. Хорошее правило: функция, которая что-то вычисляет, возвращает результат, а код, который её вызывает, решает, выводить его, сохранять или вычислять дальше.
Задание
- 1
Программа выводит
60и32, а затем завершается с ошибкойmain.lua:8: attempt to perform arithmetic on a nil value (local 'carrots'). Функцияsaleвыводит цену, а не возвращает её. Исправьте это, чтобы программа вывелаИтого монет: 92. - 2
В конце программы напишите функцию
sellPriceс параметромcrop. Она возвращает, сколько монет Эмма получает за одну штуку:5за"морковь",8за"картофель",20за"тыква"и0за всё остальное. Затем выведите однимprintзначенияsellPrice("тыква"),sellPrice("морковь")иsellPrice("камень"). Программа выводит:20 5 0 - 3
Теперь используйте обе функции вместе. В конце программы добавьте списки того, что Эмма продала сегодня:
local crops = {"морковь", "картофель", "тыква", "морковь"} local counts = {10, 5, 2, 4}Пройдите по спискам циклом
forи сложитеsale(counts[i], sellPrice(crops[i]))для каждогоi. Lua сначала вызываетsellPriceи передаёт возвращённую цену вsale. После цикла выведите итог:Монет за день: 150.