为什么nil检查失败

时间:2019-04-09 10:56:48

标签: redis lua

我正在使用Lua查询redis,并想检查是否不存在密钥,但是对于为什么我的代码无法正常工作感到困惑:

local bulk = redis.call("HMGET", KEYS[1], "p1", "p2")
for i, v in ipairs(bulk) do
    if (i == 1) then
        if (v == nil) then
            return nil  -- This is never entered
        end
    end
end

但是以下代码确实有效:

local bulk = redis.call("HMGET", KEYS[1], "p1", "p2")
for i, v in ipairs(bulk) do
    if (i == 1) then
        v = v or 0
        if (v == 0) then
            return nil  -- This does work
        end
    end
end

这是怎么回事?

1 个答案:

答案 0 :(得分:4)

您正在使用ipairs遍历表。迭代将在第一个元素nil处结束。因此v在for循环中永远不能等于nil。 因此,您永远不会输入if (v== nil)语句。

From the Lua Reference Manual 6.1 Basic Functions

  

ipairs(t)返回三个值(迭代器函数,表t,   和0),这样构造

 for i,v in ipairs(t) do body end
     

将遍历键值对(1,t [1]),(2,t [2]),...,直到第一个nil值。

实际上,您不能使用任何标准迭代器来找到nil值。

如果您只想查看bulk[1]是否为nil

替换

local bulk = redis.call("HMGET", KEYS[1], "p1", "p2")
for i, v in ipairs(bulk) do
    if (i == 1) then
        if (v == nil) then
            return nil  -- This is never entered
        end
    end
end

使用

local bulk = redis.call("HMGET", KEYS[1], "p1", "p2")
if not bulk[1] then return end

returnreturn nil相同。

如果bulk[1]可以有效地false进行显式检查,而nil则可以。

if bulk[1] == nil then return end

此代码:

local bulk = redis.call("HMGET", KEYS[1], "p1", "p2")
for i, v in ipairs(bulk) do
    if (i == 1) then
        v = v or 0
        if (v == 0) then
            return nil  -- This does work
        end
    end
end

之所以有效,是因为bulk[1]0false,在这种情况下,您将其替换为0

快速重新搜索可确认您从Redis Lua绑定中获得的是假值而不是nil。因此,使用ipairs应该没问题。您应该只检查该值是否等于false,而不是nil