使用Lua早期版本中的可变参数,但希望与5.2以上版本兼容。

我目前正在为一个 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
点赞
用户978917
用户978917

根据_Lightroom SDK 4 程序员指南(PDF)_:

Lightroom 4使用Lua语言的版本5.1.4。

由于Lua 5.1支持旧风格和新风格的varargs,因此我认为您只需使用新风格无需担心向前兼容性。

2015-12-20 03:47:52
用户3677376
用户3677376

Lua 5.1及以上版本支持新的变长参数处理风格:

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

或者,如果你真的想要每次函数调用都在一个新分配的表中获取可变参数(要注意可能有nil参数):

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

如果你还需要支持Lua 5.0,你就会遇到麻烦,因为...在引数列表之外是语法错误。你必须采用条件代码生成来解决这个问题:

-- 新版本Lua使用load而不是loadstring
local loadstring = loadstring or load
-- 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

像这样使用:

-- 两个固定参数,第三个参数保存可变参数列表
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,但你可能需要在单独的文件中编写一个独立的实现,因为这些语言存在太多的差异。

2015-12-20 15:10:04