在我的主协程中,我根据用户操作从表中删除或添加条目。在后台,我想迭代表中的条目。如果我在一次迭代中错过了插入,我并不介意,只要我可以在下一次迭代之前捕获它。
使用
pairs
迭代它安全吗?或者我应该使用 next
来代替?
您可以在遍历表时安全地删除条目,但无法创建新条目,即新键。不过,您可以修改现有条目的值。 (删除条目是该规则的特例。)
你无法从这里到达那里。至少不是直接....
正如lhf所说,您可以在遍历表时修改或删除条目,但不能添加它们。结果......未定义。 (阅读:出于所有实际目的分支到超空间或同等空间。)
如果您坚持能够添加条目,则必须克隆表并使用一个副本进行迭代,另一个副本用于跟踪插入和删除。如果这本身不符合您的要求,您将不得不这样做:
您还可以采用其他类似的模式,但规则略有不同。例如,在步骤 5 和 6 之间,您可能希望在合并之前为添加的表条目插入对表遍历代码的递归调用,等等。您可能还必须跟踪主表和添加表中可能的删除如果这是可能的互动。
next()
的文档警告:
在遍历表的过程中,不应该给表中不存在的字段赋值。不过,您可以修改现有字段。特别是,您可以将现有字段设置为 nil。
pairs()
的文档指向相同的警告(因为它在内部使用next()
),因此在pairs()
期间删除可以,但添加则不行。
ipairs()
没有指定任何限制! (它只是增加索引直到它达到零,所以插入可能会弄乱你的顺序,但行为是明确定义的。)
对于较旧的 lua: 在 5.3 上,文档使用了短语“next 的行为未定义”,这似乎更不祥。