返回介绍

2.5.8 - 函数调用

发布于 2019-08-25 13:16:35 字数 1455 浏览 1210 评论 0 收藏 0

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) -- 返回值被调整为一个

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文