我最近阅读了有关“魔兽世界”游戏的 lua 和插件。由于插件的界面语言是 lua 并且我想学习一门新语言,我认为这是一个好主意。
但有一件事我无法知道。在几乎每个插件中,顶部都有这一行,它看起来像一个构造函数,它创建一个我可以访问的成员的对象。这一行是这样的:
object = {...}
Run Code Online (Sandbox Code Playgroud)
我知道,如果一个函数返回多个值(恕我直言,这是 lua 的一大优点)并且我不想将它们单独存储在多个值中,我可以只写
myArray = {SomeFunction()}
Run Code Online (Sandbox Code Playgroud)
wheremyArray现在是一个包含值的表,我可以通过对其进行索引来访问这些值 ( myArray[4])。由于元素没有显式类型化,因为只有值本身持有它们的类型,这对 lua 来说很好。我也知道 "..." 可用于函数中的参数数组,以防函数不知道调用时获得多少参数(如String[] args在 java 中)。但是这个“大括号 - 点,点,点 - 大括号”用于什么?
您已经在问题中说明了所有内容:
{...} 实际上只是您描述的两种行为的组合:它创建了一个包含所有参数的表,所以
function foo(a, b, ...)
return {...}
end
foo(1, 2, 3, 4, 5) --> {3, 4, 5}
Run Code Online (Sandbox Code Playgroud)
基本上,...只是一个普通的表达式,就像一个返回多个值的函数调用。以下两个表达式的工作方式完全相同:
local a, b, c = ...
local d, e, f = some_function()
Run Code Online (Sandbox Code Playgroud)
请记住,这对性能有一些影响,所以也许不要在每秒调用 1000 次的函数中使用它;)
编辑:
请注意,这实际上不仅仅适用于“功能”。函数实际上比其他任何东西都更像是一种语法特性。在底层,Lua 只知道块,即函数和.lua文件都变成了块。所以,如果你运行一个 Lua 脚本,整个脚本就会变成一个块,因此与函数没有什么不同。
就代码而言,不同之处在于,对于函数,您可以在其代码之外为其参数指定名称,而对于文件,您已经处于代码的最外层;没有“外部”文件。
幸运的是,所有 Lua 文件,当它们作为一个块加载时,自动是可变参数的,这意味着它们可以...访问它们的参数列表。
当你lua script.lua foo bar在 script.lua 中调用类似 的文件时,...实际上将包含两个参数“foo”和“bar”,因此这也是在将 Lua 用于独立脚本时访问参数的便捷方式。
在您的示例中,它实际上非常相似。很可能,你的脚本在其他地方加载了load(),它返回一个你可以调用的函数——你猜对了,传递参数。
想象一下以下情况:
local a, b, c = ...
local d, e, f = some_function()
Run Code Online (Sandbox Code Playgroud)
这几乎相当于
function foo(a, b)
print(b)
print(a)
end
foo('hello', 'world')
Run Code Online (Sandbox Code Playgroud)
这是 100%(除了可能在性能上)相当于
function foo(...)
local a, b = ...
print(b)
print(a)
end
foo('hello', 'world')
Run Code Online (Sandbox Code Playgroud)