Lua 5.4中table.remove()移除nil时报下标越界错误求助
你遇到的报错bad argument #1 to 'remove' (position out of bounds)以及表长度异常变化,核心原因和Lua表的序列特性、#运算符的行为直接相关:
1. #运算符的非预期行为
Lua的#运算符计算的是表的序列长度,而非表中元素的总数。序列的定义是「从索引1开始,连续的非nil元素组成的最大集合」。如果表中存在「中间为nil、后续又有非nil元素」的情况(非合法序列),#的结果是未定义的——它会返回第一个满足t[n]~=nil且t[n+1]==nil的索引n。
你的初始表中,索引7是0.1476(非nil),索引8是nil,所以#a会返回7,而非你预期的14。这就导致你设置的tb_size = #a实际是7,循环从7开始遍历,而非14。
2. 循环中索引越界的触发
当你在循环里执行table.remove(a,j)时,该函数仅对表的序列部分生效:移除指定索引的元素后,后续序列内的元素会自动前移,同时表的序列长度会减1。
比如:当循环到j=1时,a[1]是nil,执行table.remove(a,1)后,原索引2到7的元素会前移到1到6的位置,此时表的序列长度变为6。后续循环到j=7时,当前表的序列长度已经是6,j=7超出了序列的有效索引范围,调用table.remove(a,7)就会触发「position out of bounds」错误。
另外你在print中打印a[8]到a[14]的行为会造成误导——这些元素虽然存在于表中,但属于Lua表的散列存储部分,不属于序列范畴,#和table.remove都不会对这部分元素按序列规则处理。
正确移除表中所有nil元素的方案
如果要彻底移除表中所有nil元素,建议创建新表收集非nil元素(这种方式更简单可靠):
a = { nil, -0.0227, nil, -0.1157, nil, 0.0191, 0.1476, nil, nil,nil, nil, 0.1714, nil, -0.0681} local new_a = {} for _, val in pairs(a) do if val ~= nil then table.insert(new_a, val) end end a = new_a print("处理后表长度:", #a) -- 输出结果 for idx, val in ipairs(a) do print(idx, val) end
内容的提问来源于stack exchange,提问作者ling

