Lua 中的对象表

我正在尝试创建如下的 Lua 对象

Block = {x = 0, y = 0, color = "red"}

function Block:new (x, y, color)
   block = {}
   setmetatable(block, self)
   self.__index = self
   self.x = x
   self.y = y
   self.color = color
   return block
end

然后把这个对象的多个实例放入一个单独的文件的表中

blocks = {}
table.insert(blocks, Block:new(0, 0, 'red'))
table.insert(blocks, Block:new(2, 0, 'blue'))
table.insert(blocks, Block:new(1, 1, 'green'))

for i,v in ipairs(blocks) do
    print(i,v.x, v.y, v.color)
end

但我的输出是

1   1   1   green
2   1   1   green
3   1   1   green

我该如何让这些对象在表中保留自己的实例?

原文链接 https://stackoverflow.com/questions/70017236

点赞
stackoverflow用户17439358
stackoverflow用户17439358

你应该在 block 上设置 x、y、color,而不是在 self 上设置。

function Block:new (x, y, color)
   block = {}
   setmetatable(block, {__index = self})
   block.x = x
   block.y = y
   block.color = color
   return block
end
2021-11-18 10:46:54
stackoverflow用户2858170
stackoverflow用户2858170

在你的代码中

Block = {x = 0, y = 0, color = "red"}

function Block:new (x, y, color)
   block = {}
   setmetatable(block, self)
   self.__index = self
   self.x = x
   self.y = y
   self.color = color
   return block
end

导致所有实例相同的第一个问题是,你没有将 block 设为函数的局部变量。相反,每次调用 Block.new 都会操作同一个全局变量。因此每次调用都会覆盖上一个调用的结果。

第二个问题是,你没有修改实例,而是修改了类本身。因为实例没有 xycolor,所以由于 __index 引用 Block,你会回到 Block 的值。

self 引用表格 Block,因为 function Block:new(x, y, color) 等价于 function Block.new(self, x, y, color),而你的函数调用 Block:new(0, 0, 'red') 等价于 Block.new(Block, 0, 0, 'red')

因此,你尝试创建一个名为 blockBlock 类的实例。如果你想更改该实例的属性,你必须使用 block.x = x 而不是 self.x = x,否则你将修改 Block,这将反映在所有实例上。

Block = {x = 0, y = 0, color = "red"}

function Block:new (x, y, color)
   local block = {}
   setmetatable(block, self)
   self.__index = self
   block.x = x
   block.y = y
   block.color = color
   return block
end
2021-11-18 11:38:46