lua oop 深拷贝一个 table
lua oop deep copy a 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
将其实现为 oop,但无法使其正常工作,这是我迄今为止尝试过的方法
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
在函数的 OOP 版本中,使用方法语法(冒号)的 self:deepcopy(something)
没有执行您想要的操作。相当于self.deepcopy(self, something)
;第二个参数 something
被忽略,你最终只是试图一遍又一遍地重新复制相同的 self
直到出现堆栈溢出。你必须用一个点做 self.deepcopy(something)
才能将 something
作为 self
参数(被复制的参数)传递。
在 deepcopy
方法的定义中调用 self.deepcopy
假定每个子 table 都有一个 self.deepcopy
函数。否则,您将收到 "attempt to call a nil value" 错误。但是,如果您希望每个 subtable 都有自己的 deepcopy
版本,该版本在复制 table 的直接子代时使用(键、值、metatable).例如,您可以有一个 subtable,其 deepcopy
方法不复制 metatable。这是基本版本,其中 subtable 具有相同的 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()
,您将获得该对象的副本。
我的深拷贝代码:
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
将其实现为 oop,但无法使其正常工作,这是我迄今为止尝试过的方法
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
在函数的 OOP 版本中,使用方法语法(冒号)的 self:deepcopy(something)
没有执行您想要的操作。相当于self.deepcopy(self, something)
;第二个参数 something
被忽略,你最终只是试图一遍又一遍地重新复制相同的 self
直到出现堆栈溢出。你必须用一个点做 self.deepcopy(something)
才能将 something
作为 self
参数(被复制的参数)传递。
在 deepcopy
方法的定义中调用 self.deepcopy
假定每个子 table 都有一个 self.deepcopy
函数。否则,您将收到 "attempt to call a nil value" 错误。但是,如果您希望每个 subtable 都有自己的 deepcopy
版本,该版本在复制 table 的直接子代时使用(键、值、metatable).例如,您可以有一个 subtable,其 deepcopy
方法不复制 metatable。这是基本版本,其中 subtable 具有相同的 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()
,您将获得该对象的副本。