将多个返回值存储为命名表键

时间:2014-12-21 05:27:17

标签: lua lua-table

我有一个Lua函数来计算一些值并返回它们。例如:

function calculateStats()
  return { spin=1, zoom=2, rotate=3, dist=4 }
end

在调用它的一个地方,我需要存储这些值以供以后比较。在这里,我更喜欢它们在表格中,用于命名空间:

function foo:startup()
   self.initialState = calculateStats()
end

但是,还有另一个地方,每秒多次调用此函数。为了避免不必要的垃圾收集,我宁愿不为结果分配表,而是将它们保存为局部变量。所以现在我想切换到:

function calculateStats()
  return 1, 2, 3, 4
end

function foo:onRenderFrame()
   local spin, zoom, rotate, dist = calculateStats()
end

这种不幸的副作用是我最终将我的启动功能写为:

function foo:startup()
   local spin, zoom, rotate, dist = calculateStats()
   self.initialState = {spin=spin,zoom=zoom,rotate=rotate,dist=dist}
end

是否有更好的方法将索引返回值与名称相关联并将其存储在表格中,以便我不会连续三次重复相同的名称?

4 个答案:

答案 0 :(得分:3)

您可以使用的一个简单模式是将表传递给calculateStats,然后让它返回表中的结果或者以解压缩的形式返回它。例如:

function calculateStats(t)
  if not t then return 1, 2, 3, 4 end

  t.spin, t.zoom, t.rotate, t.dist = 1, 2, 3, 4
  return t
end

这样您就可以保持foo:onRenderFrame不变,foo:startup需要进行一次小改动:

function foo:startup()
  self.initialState = calculateStats{}
end

答案 1 :(得分:1)

您可以使用某些第三方宏程序包(如LuaMacroMetaLua)来实现不错的自定义语法,或者使用类似以下Lua代码的内容:

function varargsToTable( fields, ... )
  local t = {}
  for i = 1, select( '#', ... ) do
    if fields[ i ] ~= nil then
      t[ fields[ i ] ] = select( i, ... )
    else
      break -- no more known field names left, bail out
    end
  end
  return t
end

-- maps position in return value list to field name:
statsNames = { "spin", "zoom", "rotate", "dist" }

function calculateStats()
  return 1, 2, 3, 4
end


local statsTable = varargsToTable( statsNames, calculateStats() )
for k,v in pairs( statsTable ) do
  print( k, v )
end

答案 2 :(得分:1)

虽然它仍然是两个语句,但它可以通过删除所有名称重复来满足需要,而无需在经常被调用的函数中添加条件:

function calculateStats()
  return 1, 2, 3, 4
end

function foo:startup()
   self.initialState = {}
   self.initialState.spin, self.initialState.zoom,
   self.initialState.rotate, self.initialState.dist = calculateStats()
end

function foo:onRenderFrame()
   local spin, zoom, rotate, dist = calculateStats()
end

答案 3 :(得分:1)

如果您使用的是Lua 5.2,请尝试以下操作:

local function calculateStats()
  return 1, 2, 3, 4
end

function foo:startup()
   local _ENV=self.initialState
   spin, zoom, rotate, dist = calculateStats()
end

function foo:onRenderFrame()
   local spin, zoom, rotate, dist = calculateStats()
end