Redis Lua脚本中HMGET返回值nil判断失效问题求解
问题分析:Lua脚本中HMGET返回值的类型陷阱
这问题其实是Redis和Lua脚本之间的类型映射规则在搞鬼!你踩中了一个很容易忽略的细节:Redis的HMGET命令在请求的字段不存在(或者整个键都不存在)时,返回的Null值,在Lua脚本里会被转换成Lua的false,而不是你以为的nil。
核心原因拆解
当你执行redis.call("HMGET", KEYS[1], "p1", "p2")时:
- 如果目标键
KEYS[1]不存在,或者指定的p1字段不存在,Redis会返回对应的Null值。 - 但Redis和Lua的类型转换规则里,Redis的
Null会被映射成Lua的false,而不是Lua的nil。
这就导致你第一段代码里的if (v == nil)永远不会触发——因为此时v的实际值是false,不是nil,条件不成立,自然不会执行return nil。
第二段代码为什么能生效?
你在第二段里写了v = v or 0,Lua的逻辑或or会遵循"取第一个真值"的规则:
- 因为
v是false(假值),所以v or 0会返回0。 - 接下来
if (v == 0)的条件成立,所以能正常执行return nil。
更简洁的写法建议
其实不用绕这个弯子,直接判断v是否为false就可以解决问题:
local bulk = redis.call("HMGET", KEYS[1], "p1", "p2") if bulk[1] == false then return nil end
如果你的需求只是检查p1字段是否存在,用HGET会更直接,避免处理数组的麻烦:
local p1_val = redis.call("HGET", KEYS[1], "p1") if p1_val == false then return nil end
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

