【问题标题】:What is "object = {...}" in lua good for?lua 中的“object = {...}”有什么用?
【发布时间】:2020-01-21 04:11:02
【问题描述】:

我最近阅读了有关“魔兽世界”游戏的 lua 和插件。由于插件的界面语言是lua,我想学习一门新语言,我认为这是个好主意。

但有一件事我无法了解。在几乎每个插件中,顶部都有这条线,在我看来,它就像一个构造函数,它创建了一个我可以访问的成员的对象。这一行是这样的:

object = {...}

我知道如果一个函数返回多个值(恕我直言,这是 lua 的一大优势)并且我不想将它们单独存储在多个值中,我可以写

myArray = {SomeFunction()}

其中myArray 现在是一个包含值的表,我可以通过索引它来访问这些值 (myArray[4])。由于元素没有显式类型化,因为只有值本身持有它们的类型,所以这对 lua 来说很好。我也知道“...”可以用于函数中的参数数组,以防函数不知道调用时获得多少参数(如java中的String[] args)。但是,这个“大括号-点,点,点-大括号”到底是用来做什么的???

【问题讨论】:

  • 在一个函数中,像这样:function x(...) object = {...} end,这本质上是myArray = {SomeFunction()}的操作类型,只是它将参数填充到一个表中并将该表存储在object中。跨度>
  • 我不知道三点语法在函数之外意味着什么。也许插件是作为一种调用加载的,因此具有某种形式的上下文参数?
  • 您可以在 github (github.com/AeroScripts/QuestieDev) 上查看“Questie”。在 Questie.lua 和 modules/QuestieAuto.loa 你有 _Questie = {...} 和 QuestieAuto_Questie = {...}

标签: lua


【解决方案1】:

你已经在你的问题中说了所有的内容:

{...} 实际上只是您描述的两种行为的组合:它创建了一个包含所有参数的表,所以

function foo(a, b, ...)
   return {...}
end

foo(1, 2, 3, 4, 5) --> {3, 4, 5}

基本上,... 只是一个普通的表达式,就像一个返回多个值的函数调用。以下两个表达式的工作方式完全相同:

local a, b, c = ...
local d, e, f = some_function()

请记住,尽管这会对性能产生一些影响,所以也许不要在每秒调用 1000 次的函数中使用它;)


编辑:

请注意,这实际上不仅仅适用于“函数”。函数实际上更像是一种语法特性,而不是其他任何东西。在底层,Lua 只知道块,函数和.lua 文件都变成了块。所以,如果你运行一个 Lua 脚本,整个脚本就会变成一个块,因此与一个函数没有什么不同。

就代码而言,不同之处在于,对于函数,您可以在其代码之外为其参数指定名称,而对于文件,您已经处于代码的最外层;没有“外部”文件。

幸运的是,所有 Lua 文件在作为块加载时都会自动可变参数,这意味着它们可以通过 ... 访问其参数列表。

当你在 script.lua 中调用像 lua script.lua foo bar 这样的文件时,... 实际上将包含两个参数“foo”和“bar”,因此在将 Lua 用于独立脚本时,这也是一种访问参数的便捷方式.

在您的示例中,它实际上非常相似。很可能,你的脚本在其他地方加载了load(),它返回一个你可以调用的函数——你猜对了,它传递参数。

想象以下情况:

function foo(a, b)
   print(b)
   print(a)
end

foo('hello', 'world')

这几乎等同于

function foo(...)
   local a, b = ...
   print(b)
   print(a)
end

foo('hello', 'world')

相当于 100%(性能除外)

-- Note that [[ string ]] is just a convenient syntax for multiline "strings"
foo = load([[
   local a, b = ...
   print(b)
   print(a)
]])

foo('hello', 'world')

【讨论】:

  • 在 WoW 插件的情况下(参见关于 Questie 插件的评论),此构造用于插件的顶层,中声明的函数之外添加在。但是,可能会有一些上下文从游戏传递到适合此的插件。不知道那会是什么。
  • @LasseVågsætherKarlsen 我扩展了我的答案以澄清
【解决方案2】:

Lua 5.1 Reference manual 开始,{...} 表示传递给程序的参数。在您的情况下,这些可能是从游戏传递给插件的参数。

您可以在 this questionthis thread 中看到对此的引用。

【讨论】:

    【解决方案3】:

    将以下文本放在文件的开头:

    local args = {...}
    for __, arg in ipairs(args) do
        print(arg)
    end
    

    它揭示了:

    • args[1] 是插件的名称
    • args[2] 是一个(空)表,通过引用传递给同一插件中的所有文件

    插入到 args[2] 的信息因此可用于不同的文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多