一般写的时候要注意以下几个问题:
1.自己里面的属性是自己,要防止死循环
2.同一个table地址出现在table属性(k或者v)的不同地方,复制时不能复制成2个table地址,需与原来地址保持一致
3.元表属性需要继承
function table.copy(object)
-- 已经复制过的table,key为复制源table,value为复制后的table
-- 为了防止table中的某个属性为自身时出现死循环
-- 避免本该是同一个table的属性,在复制时变成2个不同的table(内容同,但是地址关系和原来的不一样了)
local lookup_table = {}
local function _copy(object)
if type(object) ~= 'table' then -- 非table类型都直接返回
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for k,v in pairs(object) do
new_table[_copy(k)] = _copy(v)
end
-- 这里直接拿mt来用是因为一般对table操作不会很粗暴的修改mt的相关内容
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
但是这样还是有2个问题。
1.当表比较深时,递推层次很深时会不会出现栈溢出
2.userdata类型的数据在这里没有做深拷贝,还是引用了原来的值
后续可以跟进下这个问题