LUA中的对象克隆

我有如下代码,并尝试创建Test对象的副本:

local Test = {} do
    local var1, var2 = {}

    function Test:Init(val1, val2, val3)
        var1.val1 = val1
        var1.val2 = val2
        var1.val3 = val3
    end

    function Test:Print()
        print(var1.val1)
        print(var1.val2)
        print(var1.val3)
    end

    function Test:New(obj)
        obj = obj or {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end
end

然后我像这样创建对象:

local obj1 = Test:New()
obj1:Init('a','b','c')
local obj2 = Test:New()
obj2:Init('c','d','e')

obj1:Print()
obj2:Print()

结果如下:

c, d, e
c, d, e

可以看到,方法'New'没有正确地克隆对象,并且共享同一个实例。我做错了什么?我以前没有克隆过一个对象,我难以理解如何克隆。 我从这里得到了这个代码:https://www.lua.org/pil/16.2.html

谢谢。

原文链接 https://stackoverflow.com/questions/69141580

点赞
stackoverflow用户6367889
stackoverflow用户6367889

问题是因为您只是更改了局部变量,而不是对象本身。

当您执行local Test = {} do时,您并没有对Test对象做太多事情,您只是创建了表格,然后创建了一个立即执行的新范围,其中有一个名为var1的变量,该变量将通过范围共享,而不是对象。

正确的实现每个变量的方法实际上是在其上创建字段:

local Test = {} do
    function Test:Init(val1, val2, val3)
        self.val1 = val1
        self.val2 = val2
        self.val3 = val3
    end

    function Test:Print()
        print(self.val1)
        print(self.val2)
        print(self.val3)
    end

    function Test:New(obj)
        obj = obj or {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end
end

无论如何,setmetatable都不是关于克隆对象,它实现了共享行为,然后您可以使用这些行为创建任意数量的对象。

2021-09-11 13:25:27