我尝试有效地制作 lua 表的副本。我编写了以下运行良好的函数 copyTable()(见下文)。但我想我可以使用函数的“按值传递”机制获得更高效的东西。我做了一些测试来探索这种机制:
function nop(x)
return x
end
function noop(x)
x={}
return x
end
function nooop(x)
x[#x+1]=4
return x
end
function copyTable(datatable)
local tblRes={}
if type(datatable)=="table" then
for k,v in pairs(datatable) do tblRes[k]=copyTable(v) end
else
tblRes=datatable
end
return tblRes
end
tab={1,2,3}
print(tab) -->table: 0x1d387e0 tab={1,2,3}
print(nop(tab)) -->table: 0x1d387e0 tab={1,2,3}
print(noop(tab)) -->table: 0x1e76f90 tab={1,2,3}
print(nooop(tab)) -->table: 0x1d387e0 tab={1,2,3,4}
print(tab) -->table: 0x1d387e0 tab={1,2,3,4}
print(copyTable(tab)) -->table: 0x1d388d0
我们可以看到,对表的引用通过函数(当我只是阅读它或添加东西时)没有改变,除了在 noop() 中我尝试对现有的进行彻底修改。
我在这个 Q/A中阅读了Bas Bossink和Michael Anderson的回答。关于传递或表作为参数,他们强调了“通过 ref 传递的参数”和“通过值和表传递的参数是引用”之间的区别,并举例说明了这种区别。
但这究竟意味着什么?我们是否有引用的副本,但是由于指向并因此被操作的数据仍然是相同的,而不是复制的,这与传递 ref 有什么区别?当我们尝试将 nil 影响到 table 时,noop() 中的机制是否特定于避免删除 table 或在哪些情况下触发(我们可以通过 nooop() 看到,当表已修改)?
我的问题:传递表格的机制如何真正起作用?有没有一种方法可以更有效地复制表的数据而无需我的 copyTable 负担?