答案:仅在序列(数组/列表)(仅具有从 1 开始的连续整数键的表)上使用 table.* 函数。它们的行为在非类似数组的表上是未定义的:它们可能会也可能不会像您预期的那样工作。
在 Lua 5.1 table.insert( t, index, value ) 应该向上移动值,如果索引已经存在于表中,对吗?
但它并不总是这样做:
local t = {}
table.insert( t, 4, 5 )
table.insert( t, 5, 6 )
table.insert( t, 4, 4 ) -- this erase the value 5 at key 4
-- t[4] = 4, t[5] = 6, t[6] = nil
local t = {}
table.insert( t, 1 )
table.insert( t, 2 )
table.insert( t, 3 )
table.insert( t, 6, 7 )
table.insert( t, 6, 6 ) -- this erase the value 7 at key 6
-- t[6] = 6, t[7] = nil
Run Code Online (Sandbox Code Playgroud)
但 :
local t = {}
table.insert( t, 1 ) -- these two lines were added
table.insert( t, 2 )
table.insert( t, 4, 5 )
table.insert( t, 5, 6 )
table.insert( t, 4, 4 ) -- now it moves the values up
-- t[4] = 4, t[5] = 5, t[6] = 5
local t = {}
table.insert( t, 1 )
table.insert( t, 2 )
table.insert( t, 3 )
table.insert( t, 4 ) -- this line was added
table.insert( t, 6, 7 )
table.insert( t, 6, 6 ) -- now it moves the values up
-- t[6] = 6, t[7] = 7
Run Code Online (Sandbox Code Playgroud)
这在 LuaForWindows 命令行以及运行 lua 脚本 (CraftStudio) 的应用程序中的工作方式都使用 Lua 5.1。
似乎它发生在
那么,这是一个预期的行为,一个 Lua 5.1 的错误吗?是否有另一个公式可以预测这是否会发生?
非常感谢
一个表只有在它的索引是连续的时候才是一个列表: t[1], t[2], t[3], ... t[i], ... t[N] 对于所有的 i 都是非零的1 到 N。您的代码使用表作为关联数组(C++ 中的映射,Python 中的字典),因此表操作将不起作用(实际上,它们有时可能会起作用,因为它是未定义的行为)。从 Lua 5.1 参考手册:
表库中的大多数函数都假定表代表一个数组或列表。
不幸的是,ref 手册没有明确定义“数组或列表”,但浏览 ref 手册中讨论数组的地方表明,两个简单的规则足以成为“常规”或“普通”数组:t[i] 没有 nil 值对于 i=1 到 N。
您最好为 i=1 到 N 创建一个具有 t[i]=0 的表,其中 N 大于您在该函数调用中期望的任何值(例如,某个其他表中的最大值)。完成插入后,您可以将所有剩余的 t[i] which = 0 设置为 nil,但仅当您不需要 table ops 时才这样做。
您可以做的另一件事是,如果您发现应该在 i 之前插入一个项目,请检查 t[i-1] 是否为零;如果是,请将其设置为 0 或 -1 或某个代表“虚拟”的值。对 i-2 等重复此检查。