请阅读Lua Reference Manual: 3.4.7 The Length Operator
应用于表格的长度运算符返回该表格的边框。
表 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 是一个序列 -> #t1 是 t1 的长度。
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"
与t4 相同,因为t.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