Lua:完美的克隆功能,为什么不呢?

Lua:完美的克隆功能,为什么不呢?,lua,clone,lua-table,Lua,Clone,Lua Table,这是一个我一直想知道为什么不可能的问题。为什么不能实现完美的克隆功能?Lua5.3没有包含table.copy函数……我假设它可以处理所有问题/情况 我所说的各种克隆函数指的是这样的(浅、深、递归等) 资料来源:和 有人能解释一下为什么不能实现完美的克隆或复制功能吗?来扩展@lhf的完美注释。我认为这已经在Lua邮件列表上讨论过好几次了,我想说有两个原因:(1)对于一个案例来说完美合理的,对于另一个案例来说是过分的;(2) 由于元方法、upvalues和循环引用,很难完全覆盖各种情况。例如,假设

这是一个我一直想知道为什么不可能的问题。为什么不能实现完美的克隆功能?Lua5.3没有包含table.copy函数……我假设它可以处理所有问题/情况

我所说的各种克隆函数指的是这样的(浅、深、递归等)

资料来源:和

有人能解释一下为什么不能实现完美的克隆或复制功能吗?

来扩展@lhf的完美注释。我认为这已经在Lua邮件列表上讨论过好几次了,我想说有两个原因:(1)对于一个案例来说完美合理的,对于另一个案例来说是过分的;(2) 由于元方法、upvalues和循环引用,很难完全覆盖各种情况。例如,假设您使用元方法提供了一个代理表。现在,克隆后两个表共享同一个代理表,其中一个表存储的任何内容都可以被另一个表看到。这是不是一个“完美”的克隆

更具哲理,但仍然相关。完美很难实现,因为对象具有外部链接(克隆可能需要保留这些链接;或者不需要)。你有房子。你的完美克隆人是否以同样的方式拥有同样的房子?你们每人现在都拥有50%的房子吗?第三个克隆人怎么样?或者你的婚姻很幸福。你的克隆人怎么样?配偶也需要被克隆吗?在这种情况下,完美与不完美的界限在哪里


当您关心深度副本和浅层副本之间的差异时,您可能可以编写自己的函数。

处理所有情况、意外事件等。ie用户输入所需的要克隆的表,然后得到它的1:1副本(只是使用不同的名称或其他名称)克隆此:
local t;t={function()返回t;end}
解释我之前的注释。。。如果要深度复制函数值(作为表键或表值),则完美克隆将失败。你所能做的就是简单地复制它们。我想我应该再详细一点。我想要一个克隆函数,它将生成所需类中所有函数的函数指针,而AFAIK唯一的方法就是生成所有函数的克隆。我希望能够使用语法sugar调用指针:“而不是”。到目前为止,我的尝试失败了,我认为这是由于克隆功能。有人有办法吗?@TomBlodget:你可以做
loadstring(string.dump(f))
,然后使用
debug.getupvalue
/
debug.setupvalue
(可能还有
debug.upvaluejoin
)修复upvalue。
function deep (t) -- deep-copy a table
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do
        if type(v) == "table" then
            target[k] = clone(v)
        else
            target[k] = v
        end
    end
    setmetatable(target, meta)
    return target
end

function shallow (t) -- shallow-copy a table
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do target[k] = v end
    setmetatable(target, meta)
    return target
end

function copy1(obj)
  if type(obj) ~= 'table' then return obj end
  local res = {}
  for k, v in pairs(obj) do res[copy1(k)] = copy1(v) end
  return res
end


function copy2(obj)
  if type(obj) ~= 'table' then return obj end
  local res = setmetatable({}, getmetatable(obj))
  for k, v in pairs(obj) do res[copy2(k)] = copy2(v) end
  return res
end

function copy3(obj, seen)
  if type(obj) ~= 'table' then return obj end
  if seen and seen[obj] then return seen[obj] end
  local s = seen or {}
  local res = setmetatable({}, getmetatable(obj))
  s[obj] = res
  for k, v in pairs(obj) do res[copy3(k, s)] = copy3(v, s) end
  return res
end