如何检查表中是否包含__index中的某个键?

问题描述 投票:2回答:1

我想优化Fibonacci函数,但是使用表索引,memoization似乎是一个很好的方法(迭代也一样好)......然而,很快我遇到了一个问题:我无法确定一个键是否在表中。我怎样才能做到这一点?

local fib = {}

function fib_index(t, k)
   if k == 0 or k == 1 then
      t[k] = k
   else
      t[k] = t[k-1] + t[k-2]
   end
   return t[k]
end
setmetatable(fib, {__index = fib_index})
lua
1个回答
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已经计算和缓存。

© www.soinside.com 2019 - 2024. All rights reserved.