Параметры и аргументы
Функция morningChores каждый раз делает одно и то же. Но часто нужно, чтобы функция делала почти то же самое, только с другим значением каждый раз: сначала полила морковь, потом картофель. Такие значения функция получает через параметры:
local function water(crop)
print("Поливаем: " .. crop)
end
water("морковь")
water("картофель")Программа выводит:
Поливаем: морковь
Поливаем: картофельВ определении crop в скобках — это параметр: локальная переменная функции, которую она может использовать в теле. В вызове значение в скобках, "морковь", — это аргумент. Когда вы вызываете функцию, Lua кладёт аргумент в параметр, а затем выполняет тело. При первом вызове crop равен "морковь", при втором — "картофель".
Эти два слова легко перепутать, поэтому запомните: параметр — это имя в определении, аргумент — значение в вызове. Аргументом может быть и переменная, и вычисление, например water(crops[1]). Аргументы вы передаёте с первого урока: "Привет" в print("Привет") — тоже аргумент.
У функции может быть несколько параметров, через запятую. Аргументы попадают в них по порядку: первый аргумент — в первый параметр, второй — во второй и так далее:
local function plant(crop, count)
print("Посадка: " .. crop .. ", штук: " .. count)
end
plant("морковь", 12)
plant(12, "морковь")Программа выводит:
Посадка: морковь, штук: 12
Посадка: 12, штук: морковьВо втором вызове аргументы поменяли местами, поэтому 12 попало в crop, а "морковь" — в count. Lua не знает, что означают значения, — он знает только их порядок.
Во многих языках проверяется, что при каждом вызове передано ровно столько аргументов, сколько у функции параметров. В Lua такой проверки нет. Недостающий аргумент — это просто nil, а лишние отбрасываются:
local function plant(crop, count)
print(crop, count)
end
plant("пшеница")
plant("кукуруза", 5, "лишний")Программа выводит:
пшеница nil
кукуруза 5Это бывает удобно, как вы увидите в упражнении про значения по умолчанию. Но забытый аргумент — это не ошибка в вызове. Ошибка появится позже, внутри функции, там, где она использует nil:
local function plant(crop, count)
print("Посадка: " .. crop .. ", штук: " .. count)
end
plant("пшеница")Программа завершается с ошибкой:
main.lua:2: attempt to concatenate a nil value (local 'count')
stack traceback:
main.lua:2: in local 'plant'
main.lua:5: in main chunkОшибка указана в строке 2, в функции, но допущена она в вызове в строке 5. Строки под stack traceback: показывают, как программа туда попала. Читайте их снизу: основная программа (main chunk) вызвала plant в строке 5, и в строке 2 функции plant произошла ошибка. Если в сообщении об ошибке назван параметр, например local 'count', проверьте вызовы функции: все ли они передают все аргументы и в правильном ли порядке?
Задание
- 1
Эмма сажает культуры рядами, а вы будете рисовать их буквами. Напишите локальную функцию
drawRowс двумя параметрами,plantиcount. Она выводит текстplantв одной строкеcountраз: в циклеforвыводите его черезio.write, а после цикла завершите строку с помощьюprint(). - 2
Под функцией вызовите
drawRow("М", 5)для ряда из пяти морковок иdrawRow("К", 3)для ряда из трёх картофелин. Программа выводит:МММММ ККК - 3
Аргументом может быть и переменная. Грядка клубники у Эммы — треугольник: в каждом ряду на одно растение больше, чем в предыдущем. Под двумя вызовами напишите цикл
for, в которомiменяется от1до4и который вызываетdrawRow("Я", i). В каждой итерации цикла функция получает другой аргумент, поэтому программа рисует:Я ЯЯ ЯЯЯ ЯЯЯЯ