【问题标题】:Attempt to index field (nil value)尝试索引字段(零值)
【发布时间】:2020-05-28 20:14:22
【问题描述】:

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

我的代码:

Vector={
    x=nil,y=nil

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

        o.x=x or 1
        o.y=y or 1

        return o
    end

    -- utility functions here
}

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 or Vector:new()
        o.vel=vel or Vector:new()
        o.acc=acc or Vector:new()
        o.mass=mass or 1

        return 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) -- shows error that pos is nil

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

编辑:添加 Vector 实现

【问题讨论】:

  • 无法重现问题。您的代码工作正常。 b.pos 不是 nil。但是Body.pos 当然是nilBody 是一个类。 b 是实例。
  • 你能解释一下Vector是在哪里声明的吗?
  • 正如@LeszekMazur 所说,我们需要查看 Vector 实现,但是查看您的代码,我的第一个猜测是您需要将值传递给 Vector 的构造函数,因为它没有默认值价值?
  • @rm-code 添加了向量实现

标签: lua


【解决方案1】:

问题在于您的 OOP 实施。元表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)来自动检测此类问题。

【讨论】:

    猜你喜欢
    • 2012-03-12
    • 1970-01-01
    • 2019-10-10
    • 2013-06-18
    • 2011-11-05
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多