Function 为什么在函数';什么范围?
这样清除表会导致预期的行为:Function 为什么在函数';什么范围?,function,lua,scope,lua-table,Function,Lua,Scope,Lua Table,这样清除表会导致预期的行为: 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 i
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不是表1的本地“副本”,因为它是“value is reference”类型,所以它实际上是对实际表的引用。例如:
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
你没有清理桌子。您正在创建一个新表并将其分配给变量 在第一种情况下,您将覆盖
table1
变量,因此后面的引用将获得新的空表
在第二种情况下,您正在覆盖函数本地的x
变量,因此后面对table1
的引用不受影响。请注意,如果您在cleartest()
函数中说了table1={}
,它的行为将与第一种情况类似
如果确实希望清除现有表,以便对同一表的其他引用看到已清除状态,则需要编写如下内容
for k in pairs(x) do
rawset(x, k, nil)
end
你没有清理桌子。您正在创建一个新表并将其分配给变量 在第一种情况下,您将覆盖
table1
变量,因此后面的引用将获得新的空表
在第二种情况下,您正在覆盖函数本地的x
变量,因此后面对table1
的引用不受影响。请注意,如果您在cleartest()
函数中说了table1={}
,它的行为将与第一种情况类似
如果确实希望清除现有表,以便对同一表的其他引用看到已清除状态,则需要编写如下内容
for k in pairs(x) do
rawset(x, k, nil)
end
因为您实际上无法清除表的值,只能清除名称 如果你这样做
table1 = { "a" }
table1 = {}
您没有将{“a”}
设置为{}
,而是将table1
设置为{}
替换先前的值。该值现在不可访问,最终将由垃圾收集器清除
调用cleartest
时,x
也将指向与table1
相同的值{“a”}
,但x
是它的不同(本地)名称。通过执行x={}
只需使x
指向一个新的空表,但这并没有改变仍然指向{a}
的table1
的任何内容
回应您的编辑:
是x
引用的值与表1
中的值相同但是x
仍然只是碰巧指向该值的本地名称。当您将某个内容分配给x
时,局部变量x
将指向新的内容,而不会影响它以前指向的值
试试这个(无论在哪里、全球、本地,都无所谓):
将新内容分配给
test2
并打印test1
将产生相同的结果。因为您实际上无法清除表的值,而只能清除名称
如果你这样做
table1 = { "a" }
table1 = {}
您没有将{“a”}
设置为{}
,而是将table1
设置为{}
替换先前的值。该值现在不可访问,最终将由垃圾收集器清除
调用cleartest
时,x
也将指向与table1
相同的值{“a”}
,但x
是它的不同(本地)名称。通过执行x={}
只需使x
指向一个新的空表,但这并没有改变仍然指向{a}
的table1
的任何内容
回应您的编辑:
是x
引用的值与表1
中的值相同但是x
仍然只是碰巧指向该值的本地名称。当您将某个内容分配给x
时,局部变量x
将指向新的内容,而不会影响它以前指向的值
试试这个(无论在哪里、全球、本地,都无所谓):
为
test2
分配新的内容并打印test1
将产生相同的结果。x变量不是函数的局部变量,它是对实际表的引用。例如,函数内的x[2]=“b”会将表1附加到函数作用域之外。@RossCharette:你错了<代码>x是函数的本地值。但它也是对实际表格的引用。但这并不能改变这样一个事实,即对x
的赋值实际上不会影响原始表。@RossCharette:如果我有代码locala={“a”};局部b=a;b={};打印(解包(a))
,您认为会发生什么?您的问题暗示您相信它不会打印任何内容,但实际上它会打印a
,因为b
的赋值实际上没有改变a
。对x的赋值肯定会改变原始表,请参阅我在上面原始问题中的编辑,然后自己测试。@RossCharette no.x[2]=“b”
不是分配给x
x
首先作为一个名称进行计算,该名称指向您的值{“a”}
(与table1
指向的值相同)。然后,[2]=“b”
是在该值上发生的赋值。在函数内部尝试x={“b”}
:它不会更改table1
,因为这是对x
的赋值。如果你不相信凯文或我,请阅读参考手册。我用另一个澄清的例子更新了我的答案。x变量不是函数的局部变量,它是对实际表的引用。例如,函数内的x[2]=“b”会将表1附加到函数作用域之外。@RossCharette:你错了