Lua 中的函数调用的语法如下:
functioncall ::= prefixexp args
函数调用时,第一步,prefixexp 和 args 先被求值。 如果 prefixexp 的值的类型是 function, 那么这个函数就被用给出的参数调用。 否则 prefixexp 的元方法 "call" 就被调用, 第一个参数就是 prefixexp 的值,跟下来的是原来的调用参数 (参见 §2.8)。
这样的形式
functioncall ::= prefixexp `:´ Name args
可以用来调用 "方法"。
这是 Lua 支持的一种语法糖。像 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)
。
因此,如果你真的想作为成两个语句段,你必须在它们之间写上一个分号。
如果你真的想调用 f
,
你必须从 (g)
前移去换行。
这样一种调用形式:return
functioncall 将触发一个尾调用。
Lua 实现了适当的尾部调用(或是适当的尾递归):
在尾调用中,
被调用的函数重用调用它的函数的堆栈项。
因此,对于程序执行的嵌套尾调用的层数是没有限制的。
然而,尾调用将删除调用它的函数的任何调试信息。
注意,尾调用只发生在特定的语法下,
这时, return 只有单一函数调用作为参数;
这种语法使得调用函数的结果可以精确返回。
因此,下面这些例子都不是尾调用:
return (f(x)) -- 返回值被调整为一个 return 2 * f(x) return x, f(x) -- 最加若干返回值 f(x); return -- 无返回值 return x or f(x) -- 返回值被调整为一个