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

我有一个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

有没有更好的方法将索引返回值与名称相关联并将它们存储在表中,以便在短时间内不重复相同的名称?

点赞
用户3677376
用户3677376

你可以使用一些第三方宏包,比如LuaMacro或者MetaLua 来实现漂亮的自定义语法,或者使用类似下面的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

-- 映射返回值列表中的位置到字段名称:
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
2014-12-21 06:02:43
用户234175
用户234175

一个简单的模式是只需将一个表格传递给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
2014-12-21 07:23:41
用户405017
用户405017

虽然仍然包含两个语句,但这样的代码通过移除所有的名称重复,而不必将条件语句放入经常调用的函数中来满足需求:

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
2014-12-21 14:50:33
用户107090
用户107090

如果你正在使用 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
2014-12-21 23:53:37