试图索引字段(nil值)

每当我尝试使用Body.pos时,它总是说它是一个nil值。但是它在new函数中被赋值了一个值,所以它不应该为nil。

我的代码:

Vector={
    x=nil,y=nil

    ,new=function (self,x,y)
        o={}
        setmetatable(o,self)
        self.__index=self

        o.x=x或1
        o.y=y或1

        返回o
    end

    - 实用函数在这里
}

Body={
    pos=nil
    ,vel=nil
    ,acc=nil
    ,mass=nil

    ,new=function (self,pos,vel,acc,mass)
        o={}
        setmetatable(o,self)
        self.__index=self

        o.pos=pos或Vector:new()
        o.vel=vel或Vector:new()
        o.acc=acc或Vector:new()
        o.mass=mass或1

        返回o
    end

    ,applyForce=function (self,v)
        self.acc:add(v:scale(1/self.mass))
    end

    ,applyGravity=function (self)
        self.acc:add(GRAVITY_VECTOR)
    end

    ,step=function (self)
        self.vel:add(self.acc)
        self.pos:add(self.vel)

        self.acc:scale(0)
    end
}

试验代码:

b=Body:new()
print(b.pos.x) - 显示pos为nil的错误

Vector:new()不会返回nil,但是Body.pos仍然为nil。我不知道我在这里做错了什么。

编辑:添加了Vector实现

点赞
用户12730491
用户12730491

问题出在你的面向对象编程实现上。metatable o 需要被设置为局部变量。

在你的代码中,o 是一个全局变量,这就是为什么每次创建一个新对象时都会重置它的原因。

Vector = {
    -- ...
    , new = function (self, x, y)
        local o = {}
        -- ...
    end
    -- ...
}

Body = {
    -- ...
    , new = function (self, pos, vel, acc, mass)
        local o = {}
        -- ...
        return o
    end
    -- ...
}

b = Body:new()
print(b.pos.x) -- 1

基本上,任何未声明为 local 的变量都会自动放入全局变量作用域中。

此外,我建议使用一个 Linter(例如 luacheck)来自动检测此类问题。

2020-02-14 09:37:58