lua的深拷贝

lua中的赋值操作

在lua中, 如果直接将基础数据类型(除字符串和表)赋值给变量, 将会进行一次复制操作. 字符串和表则进行引用赋值. 字符串无法修改, 每次赋值和链接形成的新字符串会保存在固定区域, 字符串变量只是持有其引用. 所有的这些赋值操作都属于浅拷贝, 只是赋值值或者其引用. 当我们需要真正对表的所有内容进行复制时, 单纯的赋值操作是不够的, 我们需要进行"深拷贝".

表的深拷贝

深拷贝的原理很简单, 就是将表的基础数据类型属性(这里包含字符串类型)进行简单赋值(浅拷贝), 对表类型的属性继续进行深拷贝, 并以此迭代到最里层的属性, 直到所有的属性被拷贝完成, 注意这里表类型属性的拷贝还涉及到元表的拷贝. 下面是例子:

function deepCopy(originObj)
    local lookupTable = {}

    local _copy 
    _copy = function(obj)
        -- 基础数据类型的属性进行简单赋值操作
        if type(obj) ~= "table" then return obj end

        -- 表类型的属性进行迭代拷贝
        -- 这里的查找表是为了避免重复拷贝
        if lookupTable[obj] then return lookupTable[obj] end

        local newTable = {}
        lookupTable[obj] = newTable

        for _k, _v in pairs(obj) do
            -- 要考虑key和value为表的情况
            newTable[_copy(_k)] = _copy(_v)
        end

        -- 不要忘记复制元表
        return setmetatable(newTable, getmetatable(obj))
    end

    return _copy(originObj)
end

t = {1, 2, 333, "jdkfj", false, {4, 5, 6, {"hhh", 3}, 1}, 0, "jfdks"}
dump(deepCopy(t))

$ luajit test.lua 
- "<var>" = {
-     1 = 1
-     2 = 2
-     3 = 333
-     4 = "jdkfj"
-     5 = false
-     6 = {
-         1 = 4
-         2 = 5
-         3 = 6
-         4 = {
-             1 = "hhh"
-             2 = 3
-         }
-         5 = 1
-     }
-     7 = 0
-     8 = "jfdks"
- }

猜你喜欢

转载自blog.csdn.net/woodengm/article/details/109767444