我正在使用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
这是怎么回事?
答案 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
return
和return 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]
是0
或false
,在这种情况下,您将其替换为0
。
快速重新搜索可确认您从Redis Lua绑定中获得的是假值而不是nil。因此,使用ipairs
应该没问题。您应该只检查该值是否等于false
,而不是nil
。