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"
- }