有没有一种简单的方法在 Lua 中解包两个数组/可变参数?

让我们看一下这个伪代码示例:

-- 用给定的参数包装一个函数内部的回调
-- 对于将类方法作为回调发送非常有用。
-- 比如:callback(object.method, object)
local function callback(func, ...)
    return function(...)
         func(..., ...)
    end
end

我该怎么做? 我知道有 unpack,但它会被第二个可变参数所吞噬:

local function callback(func, ...)
    local args = { ... }
    return function(...)
         func(table.unpack(args), ...)
    end
end

callback(print, "First", "Second")("Third") --> 输出 First Third

到目前为止,我找到的唯一选择是将它们连在一起,然后解开它们:

local function callback(func, ...)
    local args1 = { ... }
    return function(...)
         local args2 = { ... }
         local args = { }
         for _, value in ipairs(args1) do
               table.insert(args, value)
         end

         for _, value in ipairs(args2) do
               table.insert(args, value)
         end

         func(table.unpack(args))
    end
end

这是唯一的解决方案吗?还是我能做得更好? 我想要的是要么有一个函数,将两个数组连接起来(这应该比那两个循环更快),然后使用 table.unpack,要么让这些可变参数连接。

点赞
用户2858170
用户2858170

Lua 5.4参考手册:3.4表达式

如果表达式用作表达式列表的最后一个(或唯一一个)元素,则不进行调整(除非表达式包含在括号中)。在所有其他上下文中,Lua将结果列表调整为一个元素,要么丢弃除第一个之外的所有值,要么添加一个单独的nil(如果没有值)。

因此,使用它们之前,唯一的方式是手动将两个列表合并为一个列表。

有几种方法可以做到这一点。

for i,v in ipairs(list2) do
  table.insert(list1,v)
end

for i,v in ipairs(list2) do
  list1[#list1+i] = v
end

table.move(list2,1,#list2,#list1+1,list1)

我不确定您实际要解决的问题是什么。如果要从其方法中访问对象,请使用self。

--用给定参数包装具有回调功能的函数 --用于将类方法发送为回调。 --例如。回调(object.method,object)

通常您会这样做:

local callback = function(params) object:method(params) end
callback(params)

而不是

callback(print,“First”,“Second”)(“ Third”)

您可以执行以下操作:

local callback = function(...) print ("First", " Second",...) end
callback(“Third”)

编辑(有见地的)

我的主要目标是将成员函数用作回调。但是,我希望保持它的通用性。回调函数的优点是省略函数和end关键字。它更短,看起来更接近,如果不需要自我参数,就会是什么样子。因此,这个:object.event = function(...)return self:method(...)end将变成这样:object.event = callback(self.method,self)什么会更好,但这不可能在lua中实现object.event = self:method

所以,您可以这样做,而不必编写function end,因此更容易?

RegisterCallback(function() obj:method()end
local function callback(func,...)
     local args1 = {...}
     返回函数(...)
          local args2 = {...}
          local args = {}
          对于_,value in ipairs(args1)do
                table.insert(args,value)
              结束

          对于_,value in ipairs(args2)do
                table.insert(args,value)
              结束

          func(table.unpack(args))
     end
end

RegisterCallback(callback(obj.method,obj)())

如果任何参数起始值为nil,则您的方法将不起作用。而且没有一个优点。您只是输入其他单词,同时增加了运行错误的机会。

2021-03-26 07:58:36
用户8294610
用户8294610

你可以控制参数顺序来优化你的函数。

local function callback(func, ...)
    local args = {...}
    return function(...)
        func(..., table.unpack(args))
    end
end

callback(print, "second", "third")("first") -- 输出 first second third
2021-03-26 09:52:22