简体   繁体   中英

Table of Objects in Lua

I'm attempting to create a Lua object like this

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

Then putting several instances of this object into a table in a separate file

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

But my output is

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

How can I get these objects to retain their own instance in the table?

In your code

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

The first problem that causes all your instances to be the same is that you did not make block local to the function. Instead each call to Block.new operates on the same global variable. So every time you call it you overwrite the result of the previous call.

The second problem is that you do not modify your instance but the class itself. As your instances don't have x , y and color you fall back to Block's value due to __index referring to Block

self refers to the table Block as function Block:new(x, y, color) is equivalent to function Block.new(self, x, y, color) and your function call Block:new(0, 0, 'red') is equivalent to Block.new(Block, 0, 0, 'red')

So you try to create an instance of the Block class named block . If you want to change that instances properties you must use block.x = x instead of self.x = x as you otherwise will alter Block which then would reflect on all instances.

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

You should be setting x,y,color on block rather then self

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM