-1

我正在尝试来自 lua.org 和我的第 4 版 Programming in Lua hardcopy 的代码,据我阅读,所有这些表格示例应该可以工作,但 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:
4

1 回答 1

4

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

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

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

换句话说,边框是表中存在的任何(自然)索引,后跟不存在的索引(或零,当索引 1 不存在时)。

只有一个边框的表格称为序列。例如,表格 {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),因为boarder == 0 and t[0+1] == nil, t[5] ~= nil and t[5+1] == nil,t[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"

t4ast.name的语法糖相同t["name"]。仅适用于有效的 Lua 名称!

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-27T20:31:41.767 回答