清除这样的表会导致预期的行为:
table1 = { "a" }
table1 = {}
print(unpack(table1)) -- results in printing a blank line
但如果你在一个函数中做同样的事情,它就不需要:
table1 = { "a" }
function cleartest (x)
x = {}
print(unpack(x))
end
cleartest(table1) -- results in printing a blank line
print(unpack(table1)) -- results in "a"
导致此行为的原因是什么?
编辑:澄清如何在Lua中传递表格。 x不是table1的本地“副本”,因为它是“值是引用”类型,它实际上是对实际表的引用。例如:
table1 = { "a" }
function xisref (x)
x[2] = "b"
end
xisref(table1)
print(unpack(table1)) -- results in printing "a b" thus x is a reference to the actual table
答案 0 :(得分:3)
因为您实际上无法清除表的值 - 只有名称。
如果你这样做
table1 = { "a" }
table1 = {}
您没有将{ "a" }
设置为{}
,但您将table1
设置为{}
,以替换之前的值。该值现在无法访问,最终将被垃圾收集器清除。
当您致电cleartest
时,x
也指向与{ "a" }
相同的值table1
,但x
是一个不同的(本地)名称。通过执行x = {}
,您只需将x
指向一个新的空表,但这不会改变table1
仍然指向{ "a" }
的内容。
回复您的修改:
是x
是对table1
的相同值的引用。 但是 x
仍然只是一个恰好指向该值的本地名称。在您向x
分配内容的那一刻,本地变量x
指向新的内容,而不会影响它之前指向的值。
尝试这个(在任何地方,全球,本地,无所谓):
test1 = { "a" }
test2 = test1
-- printing them now gives the same table
test1 = 5
-- printing test1 gives 5; printing test2 still gives the table
为test2
分配新内容并打印test1
会产生相同的结果。
答案 1 :(得分:1)
你没有清理桌子。您正在创建一个新表并将其分配给变量。
在第一种情况下,您正在覆盖table1
变量,因此后面的引用会获取新的空表。
在第二种情况下,您将覆盖函数本地的x
变量,因此稍后对table1
的引用不受影响。请注意,如果您在table1 = {}
函数中说过cleartest()
,那么它的行为就像第一种情况一样。
如果你真的想要清除现有的表,以便对同一个表的其他引用看到清除状态,你需要编写类似
的内容for k in pairs(x) do
rawset(x, k, nil)
end