Lua попытка вызвать метод nil - PullRequest
1 голос
/ 20 июня 2020

Мне сложно понять, почему этот код приводит к ошибке. Разве строка t .__ index = self не должна убедиться, что таблица t ищет функцию инициализации в векторе?

Vector = {}
Vector.init = function(self,x,y)
    self.x = x
    self.y = y
end
mt = {}
mt.__call = function(self,...)
    local t = {}
    t.__index = self
    setmetatable(t,self)
    t:init(...)
    return t
end
setmetatable(Vector,mt)
Vector.__add = function(self,other)
    return Vector(self.x+other.x,self.y+other.y)
end
local t = Vector(5,5)
local l = Vector(5,5)
local v = l + t
print(v.x,v.y)

Я также ужасен с кодом lua. Обычно я использую чужую библиотеку классов, так как не могу написать свою. Это просто сбивает меня с толку.

Я изменил свой код следующим образом.

Vector = {}
Vector.__index = Vector
Vector.mt = {}
Vector.init = function(self,x,y)
    self.x = x
    self.y = y
end
setmetatable(Vector,Vector.mt)
Vector.mt.__call = function(self,...)
    local t = {}
    setmetatable(t,self)
    t:init(...)
    return t
end
Vector.__add = function(self,other)
    return Vector(self.x+other.x,self.y+other.y)
end
local t = Vector(5,5)
local l = Vector(5,5)
local v = l + t
print(v.x,v.y)

Работает по назначению

Я придумал это как общую систему классов

Class = {}
Class.mt = {}
setmetatable(Class,Class.mt)
Class.mt.__call = function(self,name)
    local class = {}
    class.name = name
    class.__index = class
    class.mt = {}
    class.mt.__call = function(self,...)
        local t = {}
        setmetatable(t,self)
        t.init(t,...)
        return t
    end
    setmetatable(class,class.mt)
    return class
end
Vector = Class("Vector")
Vector.init = function(self,x,y)
    self.x = x
    self.y = y
end
Vector.__add = function(self,other)
    return Vector(self.x+other.x,self.y+other.y)
end

Понятия не имею, как делать наследование

Я чувствую, что сдаюсь. Я не очень хорош в этом

Кажется, я добился множественного наследования через миксины.

Просто нужно объявить суперфункции перед созданием подклассов, иначе это не будет смешивать функции.

Class = {}
Class.mt = {}
setmetatable(Class,Class.mt)
Class.mt.__call = function(self,name,...)
    local class = {}
    class.name = name
    class.parents = {...}
    class.__index = class
    class.mt = {}
    for k,v in pairs(class.parents) do
        for i,j in pairs(v) do
            if 
                i ~= "init" and 
                i ~= "parents" and 
                i ~= "mt" and 
                i  ~= "__index" and 
                i ~= "name" then class[i] = j end
        end
    end
    class.mt.__call = function(self,...)
        local t = {}
        setmetatable(t,self)
        t.init(t,...)
        return t
    end
    setmetatable(class,class.mt)
    return class
end
Vector = Class("Vector")
Vector.init = function(self,x,y)
    self.x = x
    self.y = y
end
Vector.__add = function(self,other)
    return Vector(self.x+other.x,self.y+other.y)
end
Vector.update = function()
    print("update from vector")
end
Vector3 = Class("Vector3",Vector)
Vector3.init = function(self,x,y,z)
    print("hello")
    Vector.init(self,x,y)
    self.z = z
end
Vector3.__add = function(self,other)
    local v = Vector.__add(self,other)
    return Vector3(v.x,v.y,self.z+other.z)
end
a = Vector3(1,2,3)
a.update()
print(a.z)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...