Redis - Lua表作为返回值 - 为什么这不起作用

viv*_*ekv 8 lua redis lua-table

当我通过redis EVAL运行此代码时,它不会返回任何结果.知道为什么这不起作用吗?

redis-cli EVAL "$(cat bug.lua)" 0
Run Code Online (Sandbox Code Playgroud)

bug.lua

local retv = {}
retv["test"] = 1000

return retv
Run Code Online (Sandbox Code Playgroud)

如果我初始化表,那么单独打印值.

$ cat bug.lua 
--!/usr/bin/env lua


local retv = {"This", "is", "a", "bug" }
retv["test"] = 1000

return retv

$ redis-cli EVAL "$(cat bug.lua)" 2 a b
1) "This"
2) "is"
3) "a"
4) "bug"
Run Code Online (Sandbox Code Playgroud)

del*_*eil 10

如果您参考Redis EVAL文档,您可以看到Redis用于将Lua表转换为Redis回复的规则是什么:

  1. Lua表(数组) - > Redis多批量回复(如果有的话,截断到Lua数组中的第一个nil)
  2. Lua表有一个ok字段 - > Redis状态回复
  3. 带有单个错误字段的Lua表 - > Redis错误回复

因此除了特殊情况2和3之外,Redis假设您的表是一个序列(即列表),这意味着它会retv[1], retv[2], ...在遇到nil元素之前读取(这里是相应的源代码部分).

这解释了为什么retv["test"]在您的情况下被忽略.

如果您更改代码:

local retv = {"This", "is", "a", "bug" }
retv[5] = 1000
return retv
Run Code Online (Sandbox Code Playgroud)

然后返回此附加元素:

1) "This"
2) "is"
3) "a"
4) "bug"
5) (integer) 1000
Run Code Online (Sandbox Code Playgroud)


Anv*_*aka 5

@deltheil的回答是有效的.

请记住,您可以使用cjson库打包表并将其传递给使用者.

你的lua文件:

local retv = {"This", "is", "a", "bug" }
retv["test"] = 1000

return cjson.encode(retv)
Run Code Online (Sandbox Code Playgroud)

命令:

redis-cli EVAL "$(cat bug.lua)" 0
Run Code Online (Sandbox Code Playgroud)

结果:

"{\"1\":\"This\",\"2\":\"is\",\"3\":\"a\",\"4\":\"bug\",\"test\":1000}"
Run Code Online (Sandbox Code Playgroud)