【问题标题】:LUA queue implementationLUA 队列实现
【发布时间】:2016-09-11 18:27:22
【问题描述】:

我正在尝试在Lua中实现一个简单的FIFO队列,代码如下:

dataQ = {}
dataQ.first = 0
dataQ.last = -1
dataQ.data = {}

function insert(q, val)
  q.last = q.last + 1
  q.data[q.last] = val
end

function remove(q)
    if (q.first > q.last) then 
      rval = -1
    else
      print("remove: q.data[q.first]= ", q.data[q.first], "  q.first= ", q.first)
      local rval = q.data[q.first]
      print("remove: rval= ", rval)
      q.data[q.first] = nil        -- to allow garbage collection
      q.first = q.first + 1
      print("remove: q.first= ", q.first)
    end
    return rval
end

insert(dataQ,"a")
insert(dataQ,"b")
insert(dataQ,"c")
for i,v in pairs(dataQ.data) do
    print(i, v)
end
repeat
    local x = remove(dataQ)
    print("list item= ", x)
until (dataQ.first > dataQ.last)

当我将脚本加载到 ESP8266(通过 ESPlorer)时,我收到以下 lua 解释器错误:

LUA interpreter error detected!
stdin: 1: ')' expected near ']w([[   print("remove: rval= ", rval)]]);

然而脚本运行,我得到以下输出:

1   b
2   c
0   a
remove: q.data[q.first]=    a     q.first=  0
remove: rval=   nil
remove: q.first=    1
list item=  nil

队列插入功能似乎按预期工作,但队列删除功能却没有。 remove 函数中的第一个 lua print 语句显示了 q.data[q.first] 的正确预期值,但在分配 rval 之后,该值是“nil”而不是预期的“a”

我想我在这里误解了一个基本的 lua 概念,但我无法弄清楚它是什么。

【问题讨论】:

  • @Amadan it is 在源中,remove 函数的中间:print("remove: rval= ", rval)
  • 使用 ESPlorer 0.2.0-rc3 和来自 dev 分支的最新 NodeMCU 为我工作。我的意思是我没有收到“LUA 解释器错误”。

标签: lua queue esp8266


【解决方案1】:

这是我使用 ideone 看到的输出。 http://ideone.com/72yQPs

1   b
2   c
0   a
remove: q.data[q.first]=    a     q.first=  0
remove: rval=   a
remove: q.first=    1
list item=  nil
remove: q.data[q.first]=    b     q.first=  1
remove: rval=   b
remove: q.first=    2
list item=  nil
remove: q.data[q.first]=    c     q.first=  2
remove: rval=   c
remove: q.first=    3
list item=  nil

分配给rval 工作,但remove 的返回不是因为范围错误,而是由您使用local 引起的。

else
  print("remove: q.data[q.first]= ", q.data[q.first], "  q.first= ", q.first)
  local rval = q.data[q.first]   <<< THIS rval ...
  print("remove: rval= ", rval)
  ....
end
return rval   **<<< ...is not the same variable as THIS rval.**

删除'local'关键字,你会得到这个,这可能是你所期望的。

1   b
2   c
0   a
remove: q.data[q.first]=    a     q.first=  0
remove: rval=   a
remove: q.first=    1
list item=  a
remove: q.data[q.first]=    b     q.first=  1
remove: rval=   b
remove: q.first=    2
list item=  b
remove: q.data[q.first]=    c     q.first=  2
remove: rval=   c
remove: q.first=    3
list item=  c

【讨论】:

  • else 后面的两个 print 语句在同一个范围内。由于某种原因,对 rval 的分配不起作用。我也尝试过不使用“本地”语句,并尝试将 rval 作为全局但没有区别。
  • @Jonathan 查看我的更新。我认为分配给rval 没有问题。
  • 我在 ESP8266 上使用 Nodemcu,我认为 Nodemcu 固件可能有问题。当我加载脚本时,我得到一个 LUA 解释器错误。我删除了“本地”语句,但得到了相同的结果(rval 为零)。我将与 Nodemcu 大师核实...
  • 是的,local 应该在那里删除。
【解决方案2】:

问题在于我用来将代码上传到 ESP8266 的 ESPlorer。显然,在使用 esplorer 时,您不能以 ']' 字符结束一行(感谢 github 上的 pjsg)。解决方案是切换到“turbo”模式(esplorer - 设置)。这样就消除了 Lua 错误,代码按预期运行。

【讨论】:

    【解决方案3】:
    local queue = {}
    
    table.insert(queue,'a')
    table.insert(queue,'b')
    table.insert(queue,'c')
    
    print(table.remove(queue,1)) -- a
    print(table.remove(queue,1)) -- b
    print(table.remove(queue,1)) -- c
    print(table.remove(queue,1)==nil) -- true
    

    【讨论】:

    • 欢迎来到 StackOverflow!尽管此答案可能有效,但请考虑添加更多信息/描述以帮助其他用户理解您的意思。
    猜你喜欢
    • 2014-09-03
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2014-01-04
    • 2013-03-10
    • 2013-09-22
    • 2020-08-24
    相关资源
    最近更新 更多