我有一个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
是否有更好的方法将索引返回值与名称相关联并将其存储在表格中,以便我不会连续三次重复相同的名称?
答案 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)
您可以使用某些第三方宏程序包(如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
-- 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