Ich versuche, eine Kopie einer Lua-Tabelle effizient zu machen. Ich habe die folgende Funktion copyTable() geschrieben, die gut funktioniert (siehe unten). Aber ich stellte mir vor, dass ich etwas Effizienteres haben könnte, indem ich den "Übergabewert" -Mechanismus der Funktionen nutze. Ich habe ein paar Tests, diesen Mechanismus zu erforschen:Lua: Kopieren einer Tabelle effizient (tiefe Kopie)
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
Wir können sehen, dass der Verweis auf die Tabelle durch die Funktionen unverändert übertragen wird (wenn ich es gerade gelesen oder Dinge hinzufügen), außer in noop(), wo ich versuche, eine radikale Änderung des Bestehenden.
Ich lese Bas Bossink und die Antwort von Michael Anderson in this Q/A. In Bezug auf die Übergabe oder die Tabellen als Argumente betonten sie den Unterschied zwischen "Argumente, die von ref übergeben werden" und "Argumente, die von Werten und Tabellen übergeben werden, sind Referenzen" mit Beispielen, in denen dieser Unterschied auftritt.
Aber was genau bedeutet das? Haben wir eine Kopie der Referenz, aber was für einen Unterschied macht das bei einem Ref-Durchlauf, da die Daten, die auf die Daten zeigen und daher manipuliert werden, immer noch dieselben sind, nicht kopiert? Ist der Mechanismus in noop() spezifisch, wenn wir versuchen, nil auf die Tabelle zu beeinflussen, um die Löschung der Tabelle zu vermeiden oder in welchen Fällen löst sie aus (wir können mit nooop() sehen, dass es nicht immer der Fall ist, wenn Tabelle ist modifiziert)?
Meine Frage: Wie funktioniert der Mechanismus der Weitergabe von Tabellen wirklich? Gibt es eine Möglichkeit, die Daten einer Tabelle effizienter zu kopieren, ohne dass meine CopyTable belastet wird?
Rekursion und tailcalls. Das ist so effizient wie möglich. – warspyking
@warspyking: Würde ich viel Geschwindigkeit gewinnen, im Weltraum? Wie soll ich mich für Tail Call "qualifizieren", wenn ich Sub-Tabellen zusammenstellen muss? – user1771398
https://www.lua.org/pil/6.3.html – warspyking