Lua Academy · 课时

深拷贝和浅拷贝

实现递归深拷贝,并理解引用语义。

第 3 / 4 课13 个步骤

深拷贝和浅拷贝 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

Lua 中的引用语义

在 Lua 中,将一个表赋值给另一个变量时,复制的是引用,而不是数据。两个变量指向同一个表。

local a = {1, 2, 3}
local b = a
b[1] = 99
print(a[1])  -- 99, a is affected!

浅层复制

浅层复制会创建一个新表,其中包含相同的顶层键和值。嵌套表仍然由两者共享。

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

浅层复制的局限

修改浅层副本中的嵌套表,会影响原表。

local orig = {data = {1, 2, 3}}
local sc = shallowCopy(orig)
sc.data[1] = 99
print(orig.data[1])  -- 99 (shared!)

通过递归进行深层复制

深层复制会递归复制每个嵌套表,从而断开所有共享引用。

local function deepCopy(orig)
  local copy
  if type(orig) == "table" then
    copy = {}
    for k, v in pairs(orig) do
      copy[deepCopy(k)] = deepCopy(v)
    end
    setmetatable(copy, getmetatable(orig))
  else
    copy = orig
  end
  return copy
end

深层复制的实际效果

完成深层复制后,修改副本中的嵌套表不会影响原表。

local orig = {data = {1, 2, 3}}
local dc = deepCopy(orig)
dc.data[1] = 99
print(orig.data[1])  -- 1 (independent!)

处理循环引用

朴素的深层复制会在处理循环表时出错。请在记忆表中记录已访问的表,以处理循环引用。

local function deepCopyMemo(orig, memo)
  memo = memo or {}
  if type(orig) ~= "table" then return orig end
  if memo[orig] then return memo[orig] end
  local copy = {}
  memo[orig] = copy
  for k, v in pairs(orig) do
    copy[deepCopyMemo(k, memo)] = deepCopyMemo(v, memo)
  end
  setmetatable(copy, getmetatable(orig))
  return copy
end

复制元表

深层复制还应通过 setmetatable(copy, getmetatable(orig)) 传递元表,以保留面向对象编程行为。

使用 table.move 进行浅层复制

对于连续数组,可以使用 table.move 快速创建浅层克隆。

local function arrayCopy(t)
  return table.move(t, 1, #t, 1, {})
end

如何选择

  • 浅层复制:简单的扁平表、对性能要求高的克隆操作。
  • 深层复制:嵌套结构、序列化、不可变快照。

函数值

函数不会被复制——浅层复制和深层复制都会共享同一个函数引用。这通常正是我们想要的行为。

性能注意事项

深层复制的复杂度相对于节点数量为 O(n)。对于非常大的树,可以考虑结构共享或写时复制模式。

复制类型问题

浅层复制后,修改副本中的嵌套表会发生什么?

回顾:深层复制与浅层复制

浅层复制只复制顶层键;嵌套表仍然共享。深层复制会递归复制所有内容。请使用记忆表处理循环引用,以防止无限递归。

免费开始

用 AI 导师学习 Lua — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
40
课程
159

常见问题解答

「深拷贝和浅拷贝」课时是免费的吗?

是的 — 「深拷贝和浅拷贝」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「深拷贝和浅拷贝」这节课中我会学到什么?

实现递归深拷贝,并理解引用语义。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「深拷贝和浅拷贝」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用比较器调用 table.sort
  2. table.concat 和 table.move
  3. 深拷贝和浅拷贝
  4. 转换表:map、filter、reduce
← 返回 Lua Academy