a = {x=10, y=25} b = a b.x = 99 print(a.x) |
This prints 99
but I assumed it would print 10
.
I wrote code with a start table. Then I set a position table equal to the start table. I was hoping to update the position table but reset the position back to the start point at any time I wanted. I tested this out in php to make sure I wasn't crazy and it worked like I expected. I tried it out in strict Lua but it gave the result above. Why does Lua change the a
table when I only changed the b
? How do I deal with this?
In Lua (and, off the top of my head, in JavaScript, and C#), simple types (number, string) are passed by value (i.e. values are copied from variable A into variable B), but complex types (table) are passed by reference (i.e. A and B are set to refer/point to the same table in program's memory). I can explain further if needed.
To make an actual copy of a table, try something like this:
for k,v in pairs(table1) do table2[k]=v end |
thanks, yaky. I found this page https://www.lua.org/pil/2.5.html
explaining that "A table is always anonymous. There is no fixed relationship between a variable that holds a table and the table itself"
thanks for the workaround.
@yaky Note that this will only perform a shallow copy, so tables within tables will still be passed by reference. You'd want something recursive to do a deep copy.
@Soupster
yeah.. I'm finding this out now...
start = {} start.first = {x=10, y=25} position = {} for k,v in pairs(start) do position[k] = v end position.first.x = 99 print(start.first.x) print(position.first.x) --output: --99 --99 |
was hoping for it to only change the position table, but it changes the start table as well. It did work for a single dimensional table, but I guess I'll need a for loop inside of a for loop. Seems kinda ugly.
i'm seeing this is a common problem and found this:
http://lua-users.org/wiki/CopyTable
but it all seems like a major confusion for something I normally took for granted.
--returns a copy of table t function tcopy(t) local new={} for k,v in pairs(t) do if type(v)=="table" then new[k]=tcopy(v) else new[k]=v end end return new end |
Thank you guys a million for the help. kozm0naut's simple and clear code works like a charm and I think I get it. Couldn't find anything that straightforward anywhere else.
just for completeness and because I'll probably look at this again in the future:
function tcopy(t) local new={} for k,v in pairs(t) do if type(v)=="table" then new[k]=tcopy(v) else new[k]=v end end return new end start = {x=10, y=25} position = tcopy(start) position.x = 99 print(start.x) print(position.x) --10 --99 --now revert position back to start: position = tcopy(start) print(start.x) print(position.x) --10 --10 |
[Please log in to post a comment]