【问题标题】:Lua - Size of table returning differentLua - 返回不同的表大小
【发布时间】:2019-06-17 14:26:33
【问题描述】:

伙计们。有人可以帮我解决这个问题吗?

输入

a = {}

a.c = {1,2,3}

print(#a)

print(a.c)

输出

0

table: 0x11ed7a0

为什么#a 是0?为什么不是 1?

谢谢。

【问题讨论】:

标签: lua lua-table


【解决方案1】:

它为零,因为您的表 a 不是序列。

序列是使用 1..n 中的键的表,其中 n 是序列的大小。

换句话说,# 用于序列长度,而不是表长度。

来自Lua 5.3 Reference Manual

只有一个边框的表格称为序列。例如,表 {10, 20, 30, 40, 50} 是一个序列,因为它只有一个边界 (5)。桌子 {10, 20, 30, nil, 50} 有两个边界(3 和 5),因此它不是 顺序。表格 {nil, 20, 30, nil, nil, 60, nil} 有三个边框(0, 3, 和 6),所以它也不是一个序列。表 {} 是一个边界为 0 的序列。 请注意,非自然键不会影响表是否为序列。

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

【讨论】:

    【解决方案2】:

    Lua 表是一种不同于其他语言的结构。正如Lua manual 所说:

    表是 Lua 中主要的(实际上是唯一的)数据结构机制,也是一种强大的机制。我们用表来表示普通的数组、符号表、集合、记录、队列等数据结构,简单、统一、高效。

    此外,表格具有足够的动态性,您可以同时以多种方式使用它。例如,一个表可以同时用作数组和映射。这在内部会产生一些不幸的后果。在内部,每个 Lua 表都有两部分:数组和哈希映射。

    长度运算符只对表的数组部分进行操作;没有额外的内存用于存储表中的项目总数,包括哈希映射部分。如果需要该功能,则必须手动实现。这样做的几个好方法是使用 getter 和 setter、手动更新本地计数器或使用带有 index 和 newindex 元方法的代理表。

    作为一个有趣的旁注,有时很难判断一个值是存储在表的数组部分还是散列部分中。考虑 Lua 5.3 中的这些示例:

    1: t = {true, nil, true}  -- #t = 3
    2: t = {true, [2] = true} -- #t = 2
    3: t = {true, [3] = true} -- #t = 1
    4: t = {true, true, true} t[2] = nil -- #t = 3
    

    【讨论】:

    • 一个小问题,虽然我可能会误解你:长度运算符确实考虑了表的哈希部分中的整数键。例如,在 Lua 5.3 中,t = {1, 2, nil, 4} t[5] = 5 创建了一个包含键 124 的 4 项数组部分和包含键 5 的单项哈希部分(我检查了最新版本的lua-getsize 来自 Github),但 #t5 而不是 4
    • 您给出的示例t = {1, 2, nil, 4} 在内部创建了一个大小为 8 的数组,并用数字填充位置 1、2 和 3(内部表示为 0、1 和 2)。然后它向其中添加第五个元素,该元素也适合数组。这使得数组的大小为 5.
    • 另一个有趣的注意事项是只存储数组大小,而不是数组中元素的数量。当 lua.org/source/5.3/ltable.c.html#luaH_getn"> luaH_getn 被调用时,它会从数组末尾开始对 nils 进行二进制搜索以确定长度,使 t = {true, true, true, true} t[8] = true 返回长度为 8。一些有趣的其他情况由于这种二分搜索,t = {true, true, true, true} t[6] = true --> 长度为 6,t = {true, true, true, true} t[7] = true --> 长度为 4。简而言之,稀疏数组的长度未定义。
    猜你喜欢
    • 2013-04-15
    • 2012-03-11
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多