lua中实现面向对象中deep copy的方法

以下是我的deep copy代码:

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
点赞
用户9383219
用户9383219

在函数的 OOP 版本中,使用方法语法(冒号)的 self:deepcopy(something) 并不会产生你想要的效果。它等同于 self.deepcopy(self,something);第二个参数 something 被忽略,并且您最终将一遍又一遍地尝试重新复制相同的 self,直到出现堆栈溢出。您必须使用点号进行 self.deepcopy(something),以将 something 传递为 self 参数(即被复制的参数)。

deepcopy 方法的定义内部调用 self.deepcopy 假定每个子表都有一个 self.deepcopy 函数。如果没有,则会出现“尝试调用空值”错误。但是,如果希望每个子表都有自己的 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(),您将获得一个对象的副本。

2018-12-09 09:01:34