前言:本篇文章主要讲深拷贝是如何实现的,不讲浅拷贝,不知道浅拷贝的可以去看其他博客。
意义:如果你想复制程序中的某个表的话,直接使用=号的赋值实际上是拿到了这个表的地址,本质上这两个变量存储的是同一个表,在一个变量中改变了表中某个值,相应的在另一个变量中也会改变,深拷贝的意义就是复制一个一模一样的但不是同一个的表。
实现深拷贝的代码:
t={
name="asd",hp=100,table1={
table={
na="aaaaaaaa"}}};
function copy_Table(obj)
function copy(obj)
if type(obj) ~= "table" then --对应代码梳理“1” (代码梳理在下面)
return obj;
end
local newTable={
}; --对应代码梳理“2”
for k,v in pairs(obj) do
newTable[copy(k)]=copy(v); --对应代码梳理“3”
end
return setmetatable(newTable,getmetatable(obj));
end
return copy(obj)
end
a=copy_Table(t);
for k,v in pairs(a) do
print(k,v);
end
解释:
- 核心逻辑:使用递归遍历表中的所有元素。
- 代码梳理:
1.先看copy方法中的代码,如果这个类型不是表的话,就没有遍历的必要,可以直接作为返回值赋值;
2.当前传入的变量是表,就新建一个表来存储老表中的数据,下面就是遍历老表,并分别将k,v赋值给新建的这个表,完成赋值后,将老表的元表赋值给新表。
3.在对k,v进行赋值时,同样要调用copy方法来判断一下是不是表,如果是表就要创建一个新表来接收表中的数据,以此类推并接近无限递归。
运行结果:
>lua -e "io.stdout:setvbuf 'no'" "6.17.lua"
table1 table: 00B09180
name asd
hp 100
>Exit code: 0
判断:
- 判断深拷贝后的表a和原表t是不是一个函数地址;
- 判断表a的table1中table的na是否拷贝过来了;
print(t);
print(a);
print(a.table1.table.na);
运行结果:
>lua -e "io.stdout:setvbuf 'no'" "6.17.lua"
table: 00B594A0
table: 00B59798
aaaaaaaa
>Exit code: 0