lua oop深复制表

时间:2018-12-09 01:15:02

标签: recursion lua lua-table

我的深层复制代码:

function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
    copy = {}
    for orig_key, orig_value in next, orig, nil do
        copy[deepcopy(orig_key)] = deepcopy(orig_value)
    end
    setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
    copy = orig
end
return copy
end

我正在尝试使用self实现此操作,但是无法正常工作,这是我到目前为止已经尝试过的方法

function block:deepcopy()
local orig_type = type(self)
local copy
if orig_type == 'table' then
    copy = {}
   for orig_key, orig_value in next, self, nil do
       copy[self:deepcopy(orig_key)] = deepcopy(orig_value)
   end
   setmetatable(copy, self:deeepcopy(getmetatable(self)))
else
    copy = orig
end
return copy

1 个答案:

答案 0 :(得分:1)

在该函数的OOP版本中,带有方法语法(冒号)的self:deepcopy(something)不会执行您想要的操作。它等效于self.deepcopy(self, something);第二个参数something被忽略,而您最终试图一遍又一遍地重新复制相同的self,直到出现堆栈溢出为止。您必须对点进行self.deepcopy(something),才能将something作为self参数(复制的参数)传递。

self.deepcopy方法的定义内调用deepcopy假定每个子表都有一个self.deepcopy函数。如果没有,您将收到“尝试调用nil值”错误。但是,如果您希望每个子表都有自己的deepcopy版本,该版本将在复制该表的直接子级(键,值,元表)时使用,则可以执行此操作。例如,您可能有一个子表,该子表的deepcopy方法不会复制该元表。这是基本表,其中子表具有相同的deepcopy方法:

local block = {}

function block:deepcopy()
    if type(self) == 'table' then
        local copy = {}
        for key, value in pairs(self) do
            copy[self.deepcopy(key)] = self.deepcopy(value)
        end
        return setmetatable(copy, self.deepcopy(getmetatable(self)))
    else
        return self
    end
end

block.a = { a = 10, deepcopy = block.deepcopy }
block:deepcopy() -- works

block.a = { a = 10 }
block:deepcopy() -- error: "attempt to call a nil value (field 'deepcopy')"

但是您完全不需要重写该函数即可以面向对象的方式使用它。尝试使用deepcopy的第一个定义。执行object.deepcopy = deepcopy,然后调用object:deepcopy(),您将获得该对象的副本。