Lua table拷贝函数实现

一、Lua table拷贝功能分析

在lua的table中,并没有像其它语言那样为类提供拷贝函数,所以需要开发者额外实现;

没有统一的实现的主要原因,在于table的复杂性,table可以包含各种类型的值,以及包含元表等,统一的实现并不能满足我们实际遇到的各种需求;

二、几种常见需求的实现

1.数组table的拷贝

数组table的拷贝比较简单,但是要求要拷贝的table中不能包含散列表数据,否则会丢失散列表数据;(但是这也是一种提取数组索引的数据的一种方法,就是通过unpack拿到所有的数组索引数据,然后使用{}包装起来)

function table.clone(tb)
    return {table.unpack(tb)}
end
local tb = {3, 1, 5}
local cloneTb = table.clone(tb)
table.sort(tb)
print(tb[1], cloneTb[2])

2.浅拷贝,拷贝表的最顶层数据 

最简单的浅拷贝,是扩充了数组table的拷贝,使其可以拷贝一个任意table的数据,但是只拷贝直接索引到的数据;而且不关心元表等数据;

注意:浅拷贝虽然也能拷贝到所有的数据,但是它浅拷贝的部分的数据是和其它数据共享一个table对象的,这也是称其为浅拷贝的原因;如下示例,只有最顶层的变量的数据是在新的table中的;

function table.shallowCopy(tb)
    local copy = {}
    for k, v in pairs(tb) do
        copy[k] = v
    end
    return copy
end

local tb = {x="hello", y="world" , z={name = "tb"}}
local copyTb = table.shallowCopy(tb)
print(copyTb.x) -- hello
print(copyTb.z.name) -- tb
tb.z.name = "newTb"
tb.x = "newHello"
print(copyTb.x) -- hello
print(copyTb.z.name) -- newTb

3.深拷贝,递归拷贝所有数据到新表中

如下,一个递归的深拷贝,包含了元表的深拷贝;

function table.deepCopy(tb)
    if tb == nil then
        return nil -- 参见注1
    end
    local copy = {}
    for k, v in pairs(tb) do
        if type(v) == 'table' then
            copy[k] = table.deepCopy(v)
        else
            copy[k] = v
        end
    end
    -- local meta = table.deepCopy(getmetatable(tb))
    setmetatable(copy, table.deepCopy(getmetatable(tb)))
    return copy
end

local tb = {x="hello", y="world" , z={name = "tb"}}
local copyTb = table.deepCopy(tb)
print(copyTb.x) -- hello
print(copyTb.z.name) -- tb
tb.z.name = "newTb"
tb.x = "newHello"
print(copyTb.x) -- hello
print(copyTb.z.name) -- tb

注1:在这里,如果是return而不是return nil,那么在setmetatable函数中会报错,第二个参数错误;因为在lua中nil也是一种变量类型,no return value和return nil是有区别的

上述拷贝的实现没有考虑到key为一个table类型的情况

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值