Lua:实现和理解深拷贝

前言:本篇文章主要讲深拷贝是如何实现的,不讲浅拷贝,不知道浅拷贝的可以去看其他博客。

意义:如果你想复制程序中的某个表的话,直接使用=号的赋值实际上是拿到了这个表的地址,本质上这两个变量存储的是同一个表,在一个变量中改变了表中某个值,相应的在另一个变量中也会改变,深拷贝的意义就是复制一个一模一样的但不是同一个的表。

实现深拷贝的代码:
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={
    
    };									--对应代码梳理“2for 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

判断:

  1. 判断深拷贝后的表a和原表t是不是一个函数地址;
  2. 判断表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

猜你喜欢

转载自blog.csdn.net/u011229164/article/details/106816260