Я использую 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
Что здесь происходит?
Вы используете ipairs
для перебора таблицы. Итерация закончится на первом элементе nil
. Следовательно, v
никогда не может равняться нулю внутри вашего цикла for.
Таким образом, вы никогда не войдете в оператор if (v== nil)
.
Из справочного руководства Lua 6.1 Основные функции:
ipairs (t) Returns three values (an iterator function, the table t, and 0) so that the construction
for i,v in ipairs(t) do body end
will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first nil value.
На самом деле вы не можете использовать какие-либо стандартные итераторы для поиска нулевых значений.
Если вы хотите только проверить, является ли 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
.
Быстрое исследование подтверждает, что вы получаете ложные значения вместо nil из привязок Redis Lua. Так что использование ipairs
должно быть в порядке. Вы должны просто проверить, равно ли значение false
, а не nil
.
@Джеймс, в следующий раз просто
print(bulk[1])
и ты сразу узнаешь, что этоfalse