在Lua的早期版本中使用varargs,但希望与5.2+;

在Lua的早期版本中使用varargs,但希望与5.2+;,lua,Lua,我目前正在为Lightroom插件编写代码。Lightroom不使用5.2版。我有以下功能,目前运行良好,但我担心如果Lightroom确实升级到新版本,此代码将中断。在这种情况下,您对以独立于lua版本的方式提供varargs处理有何建议 以下代码检查函数F是否用作表needsModule中的键。如果是这样,它将组成一个函数,其中包括一个将模块更改为键F指向的值的调用,然后是对函数F及其参数的调用 local function wrapFOM(F,...) local openModule

我目前正在为Lightroom插件编写代码。Lightroom不使用5.2版。我有以下功能,目前运行良好,但我担心如果Lightroom确实升级到新版本,此代码将中断。在这种情况下,您对以独立于lua版本的方式提供varargs处理有何建议

以下代码检查函数F是否用作表needsModule中的键。如果是这样,它将组成一个函数,其中包括一个将模块更改为键F指向的值的调用,然后是对函数F及其参数的调用

local function wrapFOM(F,...)
  local openModule = needsModule[F]
  if openModule == nil then
    return function() return F(unpack(arg)) end
  end
  return function()
    if LrApplicationView.getCurrentModuleName() ~= openModule then
      LrApplicationView.switchToModule(openModule)
    end
    return F(unpack(arg)) --proper tail call
  end
end
根据报告:

Lightroom 4使用Lua语言的5.1.4版


由于Lua 5.1支持旧样式和新样式的varargs,我认为您可以使用新样式,而不必担心向前兼容性。

Lua 5.1及以上版本支持新样式的vararg处理:

function vfunc( ... )
  for i = 1, select( '#', ... )
    print( i, (select( i, ... )) )
  end
end
或者,如果您真的希望在新分配的表中包含vararg,则每次函数调用(注意
nil
参数):

如果您还需要支持Lua5.0,那就太倒霉了,因为参数列表之外的
..
是一个语法错误。您必须求助于条件代码生成来避免这种情况:

-- newer Lua versions use load instead of loadstring
local loadstring = loadstring or load
-- feature test for Lua 5.1+
local supports_ellipsis = loadstring( "return ..." ) ~= nil
local args = supports_ellipsis and "{...}" or "arg"

function vararg( n, f )
  local t = {}
  for i = 1, n do t[ i ] = "_"..i end
  local params = table.concat( t, ", ", 1, n )
  local code = [[
return function( f )
  return function( ]]..params..[[, ... )
    return f( ]]..params..", "..args..[[ )
  end
end
]]
  return assert( loadstring( code, "=(vararg)" ) )()( f )
end
像这样使用它:

-- two fixed parameters, third parameter holds vararg list
local vfunc = vararg( 2, function( a, b, arg )
  print( a, b )
  for i,v in ipairs( arg ) do
    print( "", i, v )
  end
end )

vfunc( "a" )
vfunc( "a", "b" )
vfunc( "a", "b", "c" )
vfunc( "a", "b", "c", "d" )

上面的
vararg
函数的接口甚至可以用于Lua的早期版本,但是您可能需要在单独的文件中单独实现,因为语言差异太大。

使用
local arg=arg或{…}
启动函数体。更多信息@EgorSkriptunoff:你能把它作为一个答案吗?@ruakh-不幸的是,我的解决方案对于Lua5.2+中的嵌套vararg函数是不正确的(内部函数的
arg
将从外部函数继承,而不是创建新的参数数组)。我看不出好的简单的解决方案。不好的解决方案示例:
local arg=table.pack和{…}或arg
@EgorSkriptunoff:Ah,好的。我还想知道,在Lua5.1之前,您的解决方案(无论是哪一个)是否真的有效,因为
{…}
部分似乎是语法错误。。。如果您想要一个好看的解决方案,您可以将这些参数存储在一个类似堆栈的表中…(我向任何遇到这个问题的人表示歉意,他们的用例确实需要支持Lua的早期版本。我想您不会发现这个答案非常令人满意…)
-- two fixed parameters, third parameter holds vararg list
local vfunc = vararg( 2, function( a, b, arg )
  print( a, b )
  for i,v in ipairs( arg ) do
    print( "", i, v )
  end
end )

vfunc( "a" )
vfunc( "a", "b" )
vfunc( "a", "b", "c" )
vfunc( "a", "b", "c", "d" )