自己实现的深拷贝

下面是一份 Lua 版本的深拷贝实现。通过一个 lookup 表记录已经拷贝过的对象,从而解决循环引用带来的无限递归问题,同时保留原表的 metatable。

--- 深拷贝对象
-- @param srcObj 对象
local function deepCopy(srcObj)
    --- 已被拷贝的对象列表(解决循环引用的问题)
    local lookup = { }

    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup[object] then
            return lookup[object]
        end

        local newTable = { }
        lookup[object] = newTable

        for k, v in pairs(object) do
            newTable[_copy(k)] = _copy(v)
        end

        return setmetatable(newTable, getmetatable(object))
    end

    return _copy(srcObj)
end

cocos2d 提供的版本

cocos2d 提供了一份功能等价的实现,思路和上面的版本完全一致,只是命名习惯略有不同。

function clone(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for key, value in pairs(object) do
            new_table[_copy(key)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end