Справочное руководство по языку Lua 5.1 :: 2.5.8 - Получение длины



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)     -- список-результат обрезается