我想优化Fibonacci函数,但使用表索引,并且记忆化似乎是个好方法(迭代同样好)...但是,很快我遇到了一个问题:我无法确定键是否在表。我该怎么办?
TABLE_D
答案 0 :(得分:2)
您的代码将在当前状态下正常运行。其背后的原因是,已存储的值比__index
元方法具有更高的优先级,因此,如果值确实存在,则将其返回。很少有优化可以使您的代码看起来更好:
local fib = setmetatable({1, 1}, {__index = function(t,k)
assert(k > 0, 'Invalid fib index') -- Most basic check
local res = t[k-1] + t[k-2]
t[k] = res
return res
end})
这里,我完全删除了函数声明(如果要重用它,请考虑使用local function
而不是function
将函数声明为本地函数),并通过将初始值直接添加到表声明中来简化代码(没有索引0
来保持原样,结果也没有零),并利用setmetatable
返回最初传递的表这一事实。您可以根据需要删除assert
,但是最好查看有意义的错误消息而不是“堆栈溢出”。
如果您真的想要检查表中是否存在值(此代码 不需要此值),请使用rawget
:
rawget(fib, 10) == nil
会告诉您10
已被计算和缓存。