Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lua 元方法和类_Lua_Metatable_Meta Method - Fatal编程技术网

Lua 元方法和类

Lua 元方法和类,lua,metatable,meta-method,Lua,Metatable,Meta Method,我创建了一个与图中所示类似的函数,但在使用uuu add元方法时遇到了问题。我希望能够在一个类的两个实例上使用_uadd元方法,但唯一可行的方法似乎是将元方法添加到实例的元表中。有没有一种方法可以将其设置为工作状态,以便我的类或其元表可以使用uu add metamethod并在一起添加实例时工作 function Class(superClass, constructor) local class = {}; local metatable = {}; if supe

我创建了一个与图中所示类似的函数,但在使用uuu add元方法时遇到了问题。我希望能够在一个类的两个实例上使用_uadd元方法,但唯一可行的方法似乎是将元方法添加到实例的元表中。有没有一种方法可以将其设置为工作状态,以便我的类或其元表可以使用uu add metamethod并在一起添加实例时工作

function Class(superClass, constructor)
    local class = {};
    local metatable = {};

    if superClass then
        metatable.__index = superClass;
    end

    setmetatable(class, metatable);

    function metatable:__call(...)
        local instance = {};
        setmetatable(instance, { __index = class });

        if class.constructor then
            class.constructor(instance, ...);
        end

        return instance;
    end

    class.constructor = constructor;

    return class;
end
下面是我想做的一个例子:

A = Class(nil, function(self, num)
    self.num = num;
end);

function A:__add(rhs)
    return A(self.num + rhs.num);
end

a = A(1);
b = A(2);

c = a + b;

多亏了三十二上校和埃坦·赖斯纳的帮助,我想出了以下解决方案:

function metatable.__call(self, ...)
    local instance = {};
    setmetatable(instance, self);

    if class.constructor then
        class.constructor(instance, ...);
    end

    return instance;
end
function Class(superClass, constructor)
    local class = {};

    if superClass then
        for k,v in pairs(superClass) 
        do
            class[k] = v;
        end

        class._superClass = superClass;
    end

    class.__index = class;

    local metatable = {};

    function metatable:__call(...)
        local instance = {};
        setmetatable(instance, class);

        if class.constructor then
            class.constructor(instance, ...);
        end

        return instance;
    end

    class.constructor = constructor;

    setmetatable(class, metatable);

    return class;
end
我更改了函数,使其不再隐藏自变量,并将其用作实例的元表。现在添加按预期工作。然而,它在其他地方引起了问题

我尝试了在其他地方找到的一些方法,并提出了这个可行的解决方案:

function metatable.__call(self, ...)
    local instance = {};
    setmetatable(instance, self);

    if class.constructor then
        class.constructor(instance, ...);
    end

    return instance;
end
function Class(superClass, constructor)
    local class = {};

    if superClass then
        for k,v in pairs(superClass) 
        do
            class[k] = v;
        end

        class._superClass = superClass;
    end

    class.__index = class;

    local metatable = {};

    function metatable:__call(...)
        local instance = {};
        setmetatable(instance, class);

        if class.constructor then
            class.constructor(instance, ...);
        end

        return instance;
    end

    class.constructor = constructor;

    setmetatable(class, metatable);

    return class;
end

为了以防万一,我通常是这样创建类的(也很容易支持继承):


与…相似或相同?向我们展示您的代码总是比链接到其他代码要好。我很抱歉。我已经编辑了文章以包含代码。元方法必须直接在元表上。在代码中,每个实例都有自己的元表,这是浪费。将
class.\uuu index=class
添加到类初始化中,只需将每个实例的元表设置为类表即可。或者按照链接示例所做的操作,使用类表作为元表中的
\uu index
项,如果您需要额外的分离层。感谢您指出每个实例都有自己的元表。我想我没有想到这一点。我清理了_调用函数,现在它似乎按照我的预期工作。谢谢,伙计们!