Определение функций
В этом уроке вы будете писать собственные функции. Вы уже знаете несколько функций, которые есть в Lua: print, math.floor, table.insert. Каждая из них — это кусок кода, который кто-то написал один раз и дал ему имя, чтобы вы могли запустить его одной строкой столько раз, сколько нужно.
Собственные функции помогают так же. Каждое утро Эмма делает одни и те же дела, и программа, которая перечисляет их на целую неделю, повторяла бы одни и те же строки семь раз. Если бы Эмма захотела добавить новое дело, ей пришлось бы вписывать его в семи местах — и одно она бы наверняка пропустила. Вместо этого вы пишете строки один раз и даёте им имя. Такой именованный кусок кода называется функцией. Эта программа создаёт функцию с делами Эммы, а потом запускает её для двух дней:
local function morningChores()
print("Покормить кур")
print("Подоить Беллу")
end
print("Понедельник")
morningChores()
print("Вторник")
morningChores()Программа выводит:
Понедельник
Покормить кур
Подоить Беллу
Вторник
Покормить кур
Подоить БеллуПервые четыре строки создают функцию. Это называется определением функции. Определение состоит из таких частей:
local functionначинает определение.localзначит то же, что и у переменных: функция принадлежит этой программе. Почему это важно, вы увидите позже в этом уроке.- Имя, здесь
morningChores. Действуют те же правила, что и для имён переменных, и оно тоже пишется в camelCase. Выбирайте имя, которое говорит, что делает функция. - Круглые скобки
(). Пока они пустые; что в них пишут, вы узнаете в следующем упражнении. - Тело: строки, которые выполняет функция, с отступом в 4 пробела.
end, который закрывает функцию, как закрываетifи циклы.
Одно определение ничего не запускает. Без строк под ним программа ничего бы не вывела, и это не было бы ошибкой: определение лишь сообщает Lua, что должна делать функция, — как рецепт, записанный в тетрадь. Чтобы запустить функцию, её нужно вызвать: написать её имя и скобки, morningChores().
Lua выполняет программу сверху вниз. Определение он проходит мимо и только запоминает функцию. Затем он выводит Понедельник, а на вызове заходит внутрь функции, выполняет её тело и продолжает со строки после вызова. Вызовы пишутся без отступа, потому что они не входят в тело. Пустая строка после end не обязательна, но так программу легче читать.
Именно скобки делают запись вызовом. Одно имя, morningChores в отдельной строке, — синтаксическая ошибка. И print(morningChores) тоже не запускает функцию: оно выводит что-то вроде function: 0x10ead0 — так Lua выводит саму функцию.
Функция существует только со строки, где она определена. Вызвать её раньше — частая ошибка:
morningChores()
local function morningChores()
print("Покормить кур")
endПрограмма завершается с ошибкой:
main.lua:1: attempt to call a nil value (global 'morningChores')В строке 1 Lua ещё не знает никакой morningChores, поэтому у этого имени значение nil, а nil вызвать нельзя. (Что значит global, вы узнаете позже в этом уроке.) Такая же ошибка будет, если имя в вызове написано не так, как в определении, например MorningChores(): заглавные и строчные буквы различаются. Поэтому функции определяют в начале программы, а вызывают ниже.
Задание
- 1
В каждый день работы рынка программа выводит день и вывеску прилавка Эммы, поэтому три строки вывески записаны дважды. Под комментарием в начале определите локальную функцию
printSign, в теле которой выводятся три строки вывески. Запустите программу: она выведет то же, что и раньше, потому что функцию пока никто не вызывает. - 2
Замените три строки вывески под
Понедельники подВторниквызовомprintSign. Затем добавьте третий день работы рынка: выведитеСредаи ещё раз вызовитеprintSign. Вывод заканчивается так:Среда ============== Ферма «Подсолнух» ============== - 3
Эмма хочет, чтобы на вывеске было написано, чем она торгует. В теле
printSignдобавьте строку, которая выводитСвежие овощи, междуФерма «Подсолнух»и нижней линией. Запустите программу: все три вывески изменились. Вы изменили одно место в коде, и все три вызова стали делать что-то новое. Для этого и нужны функции. Программа выводит:Понедельник ============== Ферма «Подсолнух» Свежие овощи ============== Вторник ============== Ферма «Подсолнух» Свежие овощи ============== Среда ============== Ферма «Подсолнух» Свежие овощи ==============