2.5.8 – Вызовы функций
Вызовы функций в Lua имеют следующий синтаксис:
functioncall ::= prefixexp args
В вызове функции сначала вычисляются префиксное выражение и аргументы. Если
значение префиксного выражения имеет тип function, то эта функция будет вызвана с указанными
аргументами. В противном случае вызывается метаметод “call”, параметрами которого будет значение
префиксного выражения, за которым следуют первоначальные аргументы (§2.8).
Форма записи
functioncall ::= prefixexp ':' Name args
может использоваться для вызова "методов". Запись v:name(args) синтаксически аналогична записи v.name(v,args), только v вычисляется один раз.
Аргументы описываются следующим образом:
args ::= '(' [explist1] ')'
args ::= tableconstructor
args ::= String
Все выражения вычисляются перед вызовом. Вызов в форме f{fields} синтаксически аналогичен f({fields}); то есть список аргументов является по сути новой таблицей. Вызов в форме f'string' (или f"string" или f[[string]]) синтаксически равен f('string'); в данном случае список аргументов -
единстванная символьная строка.
Исключением в довольно свободном синтаксисе Lua является правило, по которому нельзя
переходить на новую строку непосредственно перед символом '(' в вызове функции. Это ограничение позволяет
избежать некоторой двусмысленности в языке. Если вы напишите
a = f
(g).x(a)
Lua трактует эту запись как выражение a = f(g).x(a). Поэтому, если вам нужно 2 выражения, вы
должны добавить точку с запятой между ними. Если вы действительно хотите
вызвать f,
вы необходимо убрать переход на новую строку перед (g).
Вызов в форме return functioncall называется
концевым вызовом. Lua также поддерживает концевой вызов «себя» (или рекурсивный
концевой вызов): в этом случае вызванная функция использует стек
вызывающей функции. Поэтому количество вложенных концовых вызовов может быть
любым. Заметим только, что концевой вызов стирает отладочную информацию о
вызывающей функции. Синтаксис концевого вызова допускает только единичный вызов
функции после оператора return.
Таким образом, return вернет в точности тот
результат, что вернет вызов функции. Ни один из представленных ниже примеров не
является допустимым концевым вызовом:
return (f(x)) -- список-результат обрезается
return 2 * f(x) -- удвоение результата функции
return x, f(x) -- возвращается несколько значений
f(x); return -- результат вызова отбрасывается
return x or f(x) -- список-результат обрезается
|