给定简单的函数:
function pullEvent()
return "eventName", "eventArg1", "eventArg2", "eventArg3", "eventArg4"
end
Run Code Online (Sandbox Code Playgroud)
其中返回值的数量取决于第一个返回值,如何将第一个返回值捕获到一个变量中并将所有剩余值捕获到列表中?
我可以想象这样的事情:
local eventName, { eventArgs } = pullEvent()
Run Code Online (Sandbox Code Playgroud)
但这是无效的语法。
我现在这样做的方式是:
local event = { pullEvent() }
local eventName, eventArgs = event[1], { table.unpack(event, 2) }
Run Code Online (Sandbox Code Playgroud)
这是可行的,但我想问是否有更短的方法。最好不创建event变量。
通常,您需要使用函数和/或select处理可变参数。在你的情况下:
local function nameAndArgs(head, ...)
return head, {...}
end
Run Code Online (Sandbox Code Playgroud)
然后您可以将其用作
-- eventArgs will be a table
local eventName, eventArgs = nameAndArgs(pullEvent())
Run Code Online (Sandbox Code Playgroud)
这个简单的解决方案假设事件参数 never nil,否则您可能会得到一个带有孔的表,其中尾随nils 被剥离;vararg1, nil, 2, nil将成为表{[1] = 1, [3] = 2}- 在较新的 Lua 版本中,您可以使用Lua 将 vararg ( )table.pack的计数存储在表的字段中,从而允许使用 准确地将其恢复为 vararg 。select("#", ...)ntable.unpack(t, 1, t.n)
然而,您很可能不想打包桌子。您想要的只是一个基于事件名称的“开关”,它将参数分配给变量。这可能如下所示:
local function handleEvent(eventName, ...)
if eventName == "foo" then
local bar = ...
-- do something
elseif eventName == "bar" then
local foobar, quux = ...
-- do something
else
error"unknown event"
end
end
handleEvent(pullEvent())
Run Code Online (Sandbox Code Playgroud)
或者,更优雅(如果您有许多处理程序,则可能更有效,因为它利用 O(1) 哈希表查找而不是平均进行 O(n) 比较),使用“函数调度表”模式:
local eventHandlers = {
foo = function(bar)
-- do something
end,
bar = function(foobar, quux)
-- do something
end,
}
local function handleEvent(eventName, ...)
return assert(eventHandlers[eventName], "unknown event")(...)
end
handleEvent(pullEvent())
Run Code Online (Sandbox Code Playgroud)