今天遇到一个麻烦的问题,查询redis时候,查到数据的时候正常返回,查询不到数据时,返回了null,然而在lua中,常见的nil,但不常见null,这时候lua中对redis返回的null如何做判断呢?
于是各种尝试。
这是经过公司基础库封装的结果,并非官方的返回,redis返回结果如下:
{"retmsg":"","result":null,"retcode":"0000"}
开始尝试了这样常规的判断,把获取的result当成字符串null,直接判断null,都已失败告终。显而易见,这个null没有双引号,lua type返回结果也没有null,最终用此方法解决
if res.result == ngx.null then
tools.logs("result is null")
end
ngx.null是什么?
那么ngx.null到底是什么东西呢? 在http://wiki.nginx.org/HttpLuaModule有如下说明:
- The ngx.null constant is a NULL light userdata usually used to
represent nil values in Lua tables etc and is similar to the
lua-cjson library’s cjson.null constant. This constant was first
introduced in the v0.5.0rc5 release.
ngx.null在print、ngx.print、ngx.log、ngx.say等函数中,有如下特点:
- Lua nil arguments are accepted and result in literal “nil” strings
while Lua booleans result in literal “true” or “false” strings. And
the ngx.null constant will yield the “null” string output.
为什么要这么设计?
lua-resty-redis中,为什么要把redis查询为空的情况返回一个userdata类型的ngx.null?直接返回nil不行吗?
答案是不行,因为nil在lua中有其特殊意义,如果一个变量被设置为nil,就等于说该变量未定义,与无穷无尽的其他未定义的变量一样。那么,如果把redis查询为空的结果设置为nil,就无法把”查询为空”和“未定义”区分开来了,例如在一个table中,一个key对应一个value,如果将该value设置为nil,则相当让key凭空消失,这显然是不合理的。所以必须用一个userdata类型的独特的值来表示这种查询为空,但又不等同于未定义的变量,例如ngx.null。同样的情况想必在sql的lua模块中也会出现,用来处理记录中键值查询为空的情况。