【发布时间】:2017-06-29 22:42:05
【问题描述】:
我尝试高效地制作 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() 中我尝试对现有的进行彻底修改。
我阅读了Bas Bossink 和Michael Anderson 在this Q/A 中的答案。关于传递或表作为参数,他们强调了“通过ref传递的参数”和“通过值和表传递的参数是引用”之间的区别,并举例说明了这种区别。
但这究竟是什么意思?我们是否有引用的副本,但是由于指向并因此被操纵的数据仍然是相同的,而不是复制的,这与通过 ref 有什么区别?当我们尝试将 nil 影响到 table 时,noop() 中的机制是否特定于避免删除 table 或在哪些情况下触发(我们可以通过 nooop() 看到,当表被修改)?
我的问题:传递表格的机制如何真正起作用?有没有一种方法可以更有效地复制表的数据而无需我的 copyTable 负担?
【问题讨论】:
-
递归和尾调用。这将与您获得的一样高效。
-
@warspyking :在太空中,我会在速度上获得很多吗?当我需要组装子表时,我应该如何“有资格”进行尾调用?
标签: lua arguments parameter-passing deep-copy pass-by-reference-value