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

时间:2015-12-19 23:25:32

标签: lua

我目前正在为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

1 个答案:

答案 0 :(得分:3)

Lua 5.1及以上支持vararg处理的新风格:

function vfunc( ... )
  for i = 1, select( '#', ... )
    print( i, (select( i, ... )) )
  end
end

或者如果你真的希望每个函数调用一个新分配的表中的varargs(小心nil参数):

function vfunc( ... )
  local args = {...}
  for i, v in ipairs( args ) do
    print( i, v )
  end
end

如果你还需要支持Lua 5.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,但是你可能需要在单独的文件中单独实现,因为语言差别太大。