lua拷贝

lua拷贝

首先要明白lua的引用类型

在 Lua 中,以下数据类型是引用类型

  • 表(table):Lua 的核心数据结构。
  • 函数(function):闭包、函数均是引用类型。
  • 线程(thread):Lua 协程(coroutine)。
  • 用户数据(userdata):外部数据的引用。

对于这些引用类型的变量,赋值或传参时,实际传递的是地址引用,而不是数据的副本。

当对引用类型赋值时,新的对象指向的都是同一个地址

a = {a = 10 , b = 20}
a1 = a
a1.c = 30
print(a.c)
--输出30

在引用传递时引用类型作为参数传递在函数中修改值同时也会修改源数据

a = {a = 10 , b = 20}
function test(a2)
    a2.d = 40
end
test(a)
print(a.d)

特殊的引用机制,弱引用表

local weaktable = {}
local strongtable = {}
--设置为弱引用表
setmetatable(weaktable,{__mode = 'kv'})
local a = {}
local b = {}
weaktable[a] = b
--strongtable[a] = b

a = nil
b = nil
collectgarbage()
for k,v in pairs(weaktable)
do
    print(k,v)
end
--输出空 因为内存被回收了
-- for k,v in pairs(strongtable)
-- do
--     print(k,v)
-- end
local weaktable = {}
local strongtable = {}
--设置为弱引用表
setmetatable(weaktable,{__mode = 'kv'})
local a = {}
local b = {}
--weaktable[a] = b
strongtable[a] = b

a = nil
b = nil
collectgarbage()
-- for k,v in pairs(weaktable)
-- do
--     print(k,v)
-- end
for k,v in pairs(strongtable)
do
    print(k,v)
end
--table: 0000000000e6b170   table: 0000000000e6b2b0

了解了引用现在正式开始lua拷贝的学习

由于lua中表是引用类型

当对表执行简单的拷贝时修改表的值会影响原表的值

在某些情境下这显然是我们不想看到的

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

-- 示例
local t1 = {a = 1, b = {x = 10, y = 20}}
local t2 = shallowCopy(t1)

t2.a = 2
t2.b.x = 30

print(t1.a)  -- 输出 1
print(t2.a)  -- 输出 2
print(t1.b.x)  -- 输出 30
print(t2.b.x)  -- 输出 30

而在这个例子中t2是t1深拷贝,因此修改t2内容将不会影响到t1

function deepCopy(original)
    local copy
    if type(original) == "table" then
        copy = {}
        for k, v in pairs(original) do
            copy[k] = deepCopy(v)  -- 递归地拷贝每个元素
        end
    else
        copy = original  -- 对于非表类型,直接拷贝
    end
    return copy
end

-- 示例
local t1 = {a = 1, b = {x = 10, y = 20}}
local t2 = deepCopy(t1)

t2.a = 2
t2.b.x = 30

print(t1.a)  -- 输出 1
print(t2.a)  -- 输出 2
print(t1.b.x)  -- 输出 10
print(t2.b.x)  -- 输出 30

给一个很好的深拷贝实现

function deepCopy(original, seen)
    seen = seen or {}
    local copy
    if type(original) == "table" then
        if seen[original] then
            return seen[original]  -- 防止循环引用
        end
        copy = {}
        seen[original] = copy
        for k, v in pairs(original) do
            copy[deepCopy(k, seen)] = deepCopy(v, seen)  -- 递归拷贝键和值
        end
    else
        copy = original  -- 对于非表类型,直接拷贝
    end
    return copy
end
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇