Lua table 示例对我不起作用

我正在尝试来自lua.org和我的第4版《Lua编程》实体书的代码,就我所读的来说,所有这些表示例都应该工作,但其中有4个中有3个不起作用,我找不到任何文档可以解释原因。希望能够帮我找出我所缺失的东西。我认为某些规范已经改变了,就像我已经发现table.getn()不再可用一样。我的Linux系统有Lua 5.3.5

local t1={}
t1[1]="Foo"
t1[2]="Bar"
print("Size: "..#t1)
print("Works:"..table.concat(t1,'$$'))

local t2={}
t2[5]="Foo"
t2[40]="Bar"
print("Size: "..#t2)
print("Doesnt Work:"..table.concat(t2,'$$'))

local t3={}
t3["A"]="Foo"
t3["B"]="Bar"
print("Size: "..#t3)
print("Doesnt Work:"..table.concat(t3,'$$'))

local t4={}
t4.A="Foo"
t4.B="Bar"
print("Size: "..#t4)
print("Doesnt Work:"..table.concat(t4,'$$'))

结果

Size: 2
Works:Foo$$Bar
Size: 0
Doesnt Work:
Size: 0
Doesnt Work:
Size: 0
Doesnt Work:
点赞
用户2858170
用户2858170

请阅读 Lua 参考手册:3.4.7 长度运算符

应用于表的长度运算符将返回该表的边缘。 表t的边缘是任何满足以下条件的自然数:

(border == 0 or t[border] ~= nil) and t[border + 1] == nil

换言之,边缘是存在于表中的任何(自然数)索引,紧随其后的一个索引是不存在的(或者当索引1不存在时,为0的情况)。

仅有一个边缘的表称为序列。例如,表{10,20,30,40,50}是序列,因为它仅有一个边缘(5)。表{10,20,30,nil,50}有两个边缘(3和5),因此它不是序列。(索引4处的nil称为“洞”)。表{nil,20,30,nil,nil,60,nil}有三个边缘(0、3和6)和三个洞(位于索引1、4和5),因此它也不是序列。表{}是边缘为0的序列。注意,非自然键不会干扰表是否为序列的判断。

t是序列时,#t返回它唯一的边缘,这对应于序列长度的直观概念。当t不是序列时,#t可以返回任何边缘。(具体取决于表的内部表示的细节,这又取决于表的填充方式和其非数字键的内存地址。)

应用于您的示例:

local t1={}
t1[1]="Foo"
t1[2]="Bar"

t1仅有一个边缘(2),因为t1[2] ~= nil and t1[2+1] == nil

t1只有1个边缘-> t1是序列-> #t1t1的长度。

local t2={}
t2[5]="Foo"
t2[40]="Bar"

t2有3个边缘(0、5、40),因为border == 0 and t[0+1] == nilt[5] ~= nil and t[5+1] == nilt[40]~=nil and t[40+1]==nil

t2有多个边缘-> #t2是其任意边缘,而不是其长度。

local t3={}
t3["A"]="Foo"
t3["B"]="Bar"

t3有1个边缘(0),因为border == 0 and t3[0+1] == nil,没有更多数字键,因此没有更多的边缘。t3仅有一个边缘-> t3是长度为0的序列。

local t4={}
t4.A="Foo"
t4.B="Bar"

t4等价,因为t.namet["name"]的语法糖。仅适用于有效的Lua名称!

t1是您示例中唯一的序列,因此唯一的t1#运算符返回元素数的表。

如果您不确定是否有序列,则应按如下方式计算元素数:

local n = 0
for _ in pairs(t) do
  n = n + 1
end

这是如何打印表t的边缘:

function printBorders(t)
  local borders = {}
  for k in pairs(t) do
    if type(k) == "number" and
      t[k] ~= nil and t[k+1] == nil then
      table.insert(borders, k)
    end
  end
  if t[1] == nil then table.insert(borders, 0) end
  table.sort(borders)
  print(table.concat(borders, ", "))
end
2021-03-27 20:31:41