【问题标题】:Redis - Lua tables as return values - why is this not workingRedis - Lua 表作为返回值 - 为什么这不起作用
【发布时间】:2014-08-09 12:41:39
【问题描述】:

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

redis-cli EVAL "$(cat bug.lua)" 0

bug.lua

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

return retv

如果我初始化表,则仅打印该值。

$ 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"

【问题讨论】:

  • 您的实际命令在 0 之前是否有结束引号?没有它就行不通,想知道是错字还是真实
  • 是的,你是对的。这只是一个错字。我在命令行上有它。解决问题。感谢您指出。
  • 如果bug.lua 有local msg = "hi"; return msg 会起作用吗?如果您 cat 一个不存在的文件,您会收到错误消息吗?您正在返回对表的引用,而不是表的字符串表示形式,Redis 是否知道如何显示引用(本质上是指针)?
  • Lua 解释器工作正常并且加载文件也很好。两者都检查过。
  • 至于表引用的返回,Redis 手册 (redis.io/commands/eval) 说 Lua 表被转换为适当的 redis 数据结构。所以我不确定那里是否有问题。

标签: lua redis lua-table


【解决方案1】:

如果您参考Redis EVAL documentation,您可以看到 Redis 使用什么规则将 Lua 表转换为 Redis 回复:

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

因此,除了特殊情况 2 和 3,Redis 假定您的表是一个序列(即列表),这意味着它会读取retv[1], retv[2], ...,直到遇到nil 元素(这里是对应的source code section)。

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

如果您更改代码:

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

然后这个额外的元素被返回:

1) "This"
2) "is"
3) "a"
4) "bug"
5) (integer) 1000

【讨论】:

  • 就是这样。 Redis 不支持 Lua 的任意表。不知道!非常感谢。
  • 是的!这是因为它需要将 Lua 返回的值转换为有效的Redis protocol(又名 RESP)数据类型,即简单字符串、错误、整数、批量字符串和数组——并且没有关联数组。
  • 非常感谢。这对我帮助很大! deltheil 还写了重要的句子“......没有关联数组”,这有助于我找出问题所在!
【解决方案2】:

@deltheil 的回答是有效的。

请记住,您可以使用 cjson 库来打包表格并将它们传递给消费者。

你的 lua 文件:

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

return cjson.encode(retv)

命令:

redis-cli EVAL "$(cat bug.lua)" 0

结果:

"{\"1\":\"This\",\"2\":\"is\",\"3\":\"a\",\"4\":\"bug\",\"test\":1000}"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 2014-04-12
    • 2015-03-18
    • 1970-01-01
    • 2020-12-14
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多