2

像这样清除表会导致预期的行为:

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
4

2 回答 2

3

因为您实际上无法清除表的值 - 只能清除名称。

如果你这样做

table1 = { "a" }
table1 = {}

您没有设置{ "a" }{},但您设置table1{}替换以前的值。该值现在无法访问,最终将被垃圾收集器清除。

当您调用 时cleartest,thenx将指向与 相同的值,但它是不同的(本地)名称。通过这样做,您只需指向一个新的空表,但这并没有改变仍然指向.{ "a" }table1xx = {}xtable1{ "a" }

回应您的编辑:

Yesx是对与 相同的值的引用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会产生相同的结果。

于 2013-03-22T22:26:24.400 回答
1

你不是在清理桌子。您正在创建一个新表并将其分配给变量。

在第一种情况下,您正在覆盖table1变量,因此后面的引用会获取您的新空表。

在第二种情况下,您将覆盖x函数本地的变量,因此后面的引用table1不受影响。table1 = {}请注意,如果您在函数中说过,cleartest()它的行为将与第一种情况类似。

如果您确实想清除现有表,以便对同一表的其他引用看到已清除状态,您需要编写类似

for k in pairs(x) do
    rawset(x, k, nil)
end
于 2013-03-22T22:24:58.673 回答