LUA队列实现

我正在尝试在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        -- 允许垃圾回收
      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解释器错误!
stdin:1:')'附近应该有']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打印语句显示q.data \ [q.first ]的预期值是正确的,但在分配rval后,该值的值为“nil”,而不是预期的“a”

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

点赞
用户1737
用户1737

以下是在 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]   <<< 这里的 rval ...
  print("remove: rval= ", rval)
  ....
end
return rval   **<<< 不同于这个 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
2016-05-16 08:54:50
用户6220957
用户6220957

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

2016-05-16 21:34:54
用户6544989
用户6544989
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

本代码演示了如何使用 Lua 中的表作为队列来使用。表 queue 中第一个插入的元素为队列头部,而最后插入的元素则在队列的尾部。使用 table.remove(queue,1) 可以取出队列头部的元素,即先进先出。在本代码中,a 是队列中的第一个元素,因此先被移除,随后是 bc 依次被取出,最后再试图移除已经取出的连接,得到 nil,表明队列已经被取空。

2016-07-15 15:45:45