Справочное руководство по языку Lua 5.1 :: 2.5.9 - Получение длины
2.5.9 – Объявление функций
Синтаксис объявления функций:
function ::= function funcbody
funcbody ::= '(' [parlist1] ')' block end
Или в упрощенном виде
stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {'.' Name} [':' Name]
Выражение
function f () body end
транслируется в
f = function () body end
Выражение
function t.a.b.c.f () body end
транслируется в
t.a.b.c.f = function () body end
Выражение
local function f () body end
транслируется в
local f; f = function () body end
а не в
local f = function () body end
(Разница проявится в том случае, если в теле функции используется имя этой функции, например при рекурсивном вызове)
Объявление функции является выполняемым выражением, его результатом будет значение типа function. Когда Lua прекомпилирует порцию, тела всех упоминающихся в ней функций также прекомпилируются. Таким образом, всякий раз, когда Lua обрабатывает объявление функции, функция уже конкретизирована (или замкнута). Этот конкретный экземпляр функции (или замыкание) и является конечным значением выражения «объявление функции». Различные экземпляры одной и той же функции могу ссылаться на различные внешние локальные переменные и иметь различные таблицы окружения.
Параметры функции фактически являются локальными переменными, которые инициализированы входными значениями:
parlist1 ::= namelist [',' '...'] | '...'
В момент вызова функции длина списка передаваемых параметров приводится в соответствие спецификации, если это не функция с неопределенным количеством параметров. Для функций с неопределенным количеством параметров такая коррекция не проводится; все входные параметры попадают в функцию в виде неопределенного выражения, которое также обозначается с тремя точками. Значением этого выражения является список всех полученных входных параметров, как в случае множественного результата функции. Еслы неопределенное выражение используется внутри другого выражения или в середине списка выражений, то его значение-список урезается до одного элемента. Если это выражение стоит в конце списка выражений, урезания не происходит (если конечно вызов не заключен в круглые скобки).
Рассмотрим следующие объявления:
function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 end
Пример отображения входных значений на параметры функции:
ВЫЗОВПАРАМЕТРЫ
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4
f(r(), 10) a=1, b=10
f(r()) a=1, b=2
g(3) a=3, b=nil, ... --> (ничто)
g(3, 4) a=3, b=4, ... --> (ничто)
g(3, 4, 5, 8) a=3, b=4, ... --> 5 8
g(5, r()) a=5, b=1, ... --> 2 3
Результаты возвращаются из функции оператором return (см. §2.4.4). . Если управление достигает конца функции, а оператор return не встретился, то функция завершается и ничего не возвращает.
Синтаксис с двоеточием ‘:’ используется для определения методов. Эти функций неявно получают параметр self в качестве первого аргумента. Таким образом, выражение
function t.a.b.c:f (params) body end
аналогично
t.a.b.c.f = function (self, params) body end