【问题标题】:Lua Object Oriented object IDs don't incrementLua 面向对象的对象 ID 不会增加
【发布时间】:2014-09-10 00:17:41
【问题描述】:

我正在尝试为 LOVE 创建一个对象,该对象将为自己提供自己的 ID。基本上,每次我创建这个对象时,它的 self.id 都应该加一。但是,如果我连续创建 5 个新对象,则 ID 将为 4(因为它从 0 开始)。

但是,如果我创建对象然后手动更改 ID,它会正确保存,并且该对象不再“绑定”到 idcounter。

entities = {}
idcounter = 0

Entity = {id = -1, test=0}
function Entity:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    self.id = idcounter
    idcounter = idcounter + 1
    entities[idcounter] = self
    return o
end

function Entity:GetID()
    return self.id
end

function Entity:SetTest(v)
    self.test = v
end

function Entity:GetTest()
    return self.test
end

test = Entity:new()
test2 = Entity:new()

print(test:GetID())
print(test2:GetID())
test.id = 10
print(test:GetID())
print(test2:GetID())
for k,v in pairs(entities) do
    print(test)
end
test3 = Entity:new()
print(test:GetID())
print(test2:GetID())
for k,v in pairs(entities) do
    print(test)
end

打印出来的

1
1
10
1
table: 00789020
table: 00789020
10
2
table: 00789020
table: 00789020
table: 00789020

其中的表格部分特别令人沮丧,因为我希望能够遍历我制作的所有实体的数组,但它们似乎都指向同一个实体。

我做错了什么?

【问题讨论】:

  • 您正在循环中打印出test 的值。不是v 的值,它是当前循环条目的实体。 pairs 也不保证遍历顺序。
  • 您还在:new() 函数中设置Entities.id,而不是您创建的实体o.id
  • 哇哦!我对第一个数字感到非常尴尬。让我直接说第二部分:self 和 Entity 一样吗?将 self.id 更改为 o.id 修复了第一部分,但将循环中的打印更改为 print(tostring(v) .. " " .. v:GetID()) 会使它们打印相同的表格代码和 -1。
  • 哦,修好了。我也有entities[idcounter] = self,正如你所指出的,self 是不对的。非常感谢!
  • self 是函数的第一个参数(当函数使用: 语法定义时为隐式)。当调用Entity:new()(与Entity.new(Entity) 相同)时,selfEntity。当调用test:GetId() 时,selftest

标签: oop lua love2d


【解决方案1】:

第一个问题是new()方法中self的含义。这实际上是指实体元表而不是您正在创建的对象。因此,当您设置 self.id 时,您设置的是类字段而不是对象字段。

要纠正此问题,您需要将其更改为将 o.id 设置为计数器,然后每个对象将获得不同的 id。顺便说一句,test.id = 10 工作时发生的事情是您将对象的 id 设置为 10,这会覆盖元表的。

第二点与entities 表有关。 Lua 喜欢将表作为 1 索引数组或字典。通过从 0 开始索引并覆盖索引,你可以让它在两者之间做一些事情,所以它不太可能完全按照你的意愿去做。我的建议是将entity 列表从对象的id 中分离出来,这样您就可以始终将entities 作为一个数组进行遍历。缺点是您将无法执行诸如 entities[id] 之类的代码来检索具有该 ID 的对象。

所以从代码的角度来看:

function Entity:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    o.id = idcounter
    o.test = "test "..idcounter
    idcounter = idcounter + 1
    entities[#entities+1] = o
    return o
end

for k,v in ipairs(entities) do
    print(v.test)
end

【讨论】:

    猜你喜欢
    • 2022-01-05
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多