将对象传递给Lua函数总是引用self
我试图在Lua中创建一个对象房间,该房间上有一个功能,用于检查提供的另一个房间是否与之相交 我遇到了一个问题,我作为参数传入的内容似乎总是与我调用函数的对象相同将对象传递给Lua函数总是引用self,lua,Lua,我试图在Lua中创建一个对象房间,该房间上有一个功能,用于检查提供的另一个房间是否与之相交 我遇到了一个问题,我作为参数传入的内容似乎总是与我调用函数的对象相同 Room = { Width = 0, Height = 0, X = 0, Left = 0, Right = 0, Top = 0, Bottom = 0 } function Room:new(width, height, x, y) self.Width = wi
Room = {
Width = 0,
Height = 0,
X = 0,
Left = 0,
Right = 0,
Top = 0,
Bottom = 0
}
function Room:new(width, height, x, y)
self.Width = width
self.Height = height
self.X = x
self.Y = y
self.Left = x
self.Right = self.X + self.Width
self.Top = y
self.Bottom = self.Y + self.Height
return self
end
function Room:Intersects(other)
print("Checking for intersection...")
print("Self X: ", self.X)
print("Self Y: ", self.Y)
print("Other X: ", other.X)
print("Other Y: ", other.Y)
return other.Left < self.Right and self.Left < other.Right and other.Top < self.Bottom and self.Top < other.Bottom
end
room1 = Room:new(5, 6, 3, 3)
room2 = Room:new(10, 16, 5, 9)
intersects = room1:Intersects(room2)
print("Intersects: ", intersects)
我希望self.X,self.Y与其他.X和其他.Y不同。我一直在关注Lua.org的章节。房间是顶部定义的一个表,对房间的所有引用都作用于同一个表,而不是不同的对象 下面的解决方案创建一个名为“obj”的不同表,并在每次调用NewRoom时返回此唯一表。此方法大致类似于您参考的指南第16.4章
function NewRoom(width, height, x, y)
local obj = {
Width = width,
Height = height,
X = x,
Y = y,
Left = x,
Right = x + width,
Top = y,
Bottom = y + height,
}
function obj:Intersects(other)
print("Checking for intersection...")
print("Self X: ", self.X)
print("Self Y: ", self.Y)
print("Other X: ", other.X)
print("Other Y: ", other.Y)
return other.Left < self.Right and self.Left < other.Right and other.Top < self.Bottom and self.Top < other.Bottom
end
return obj
end
room1 = NewRoom(5, 6, 3, 3)
room2 = NewRoom(10, 16, 5, 9)
intersects = room1:Intersects(room2)
print("Intersects: ", intersects)
Room是在顶部定义的单个表,对Room的所有引用都作用于同一个表,而不是不同的对象 下面的解决方案创建一个名为“obj”的不同表,并在每次调用NewRoom时返回此唯一表。此方法大致类似于您参考的指南第16.4章
function NewRoom(width, height, x, y)
local obj = {
Width = width,
Height = height,
X = x,
Y = y,
Left = x,
Right = x + width,
Top = y,
Bottom = y + height,
}
function obj:Intersects(other)
print("Checking for intersection...")
print("Self X: ", self.X)
print("Self Y: ", self.Y)
print("Other X: ", other.X)
print("Other Y: ", other.Y)
return other.Left < self.Right and self.Left < other.Right and other.Top < self.Bottom and self.Top < other.Bottom
end
return obj
end
room1 = NewRoom(5, 6, 3, 3)
room2 = NewRoom(10, 16, 5, 9)
intersects = room1:Intersects(room2)
print("Intersects: ", intersects)
正如Dahk所说,您定义的房间表也是作为新房间对象返回的房间表。 房间:方法。。。是Room.methodRoom 当您使用速记时,Lua提供的self变量包含对Room的引用,因此当您键入Room:new5、6、3、3时,Lua读取的是Room.newRoom,5、6、3、3,其中self=Room。当我们让self.width=5时,发生的是Room.width=5,而这不是我们想要发生的 为了解决这个问题,我们需要在每次调用Room:new时创建一个新对象。我们创建一个名为obj的新表,然后将值存储在该表中
function Room:new(width, height, x, y)
local obj = {
Width = width,
Height = height,
X = x,
Y = y,
Left = x,
Right = x + width,
Top = y,
Bottom = y + height,
}
return obj
end
这很好,我们现在可以创建房间了。但当我们尝试执行room1:Intersect时,我们得到了一个错误:方法Intersects未定义。我们可能定义了一个新房间,但这个房间只不过是一张简单的桌子。这就是元表的用武之地。简言之,元表定义了表的行为。在我们的例子中,我们希望它包含一个值,以便Lua在原始列表中找不到值或方法时可以查看。有关元表的更多信息,请参见
让我们看一个例子:
如果每个房间的地板都是一样的,我们可以把这个地板复制给每个孩子,或者让room.floor=地毯,当有人问我们某个房间的地板是什么时,我们就回到这里。回到这里,我们使用元表和方法。这个方法是Lua查找它找不到的值的地方
function Room:new(width, height, x, y)
local obj = {
...
}
setmetatable(obj, self) -- self here is equal to Room
self.__index = self
return obj
end
我们再次创建对象,其中包含要分别为每个房间存储的所有值。其次,我们让Room成为obj的元表。第三行告诉我们,当找不到任何方法时,应该使用房间表。
在创建对象期间使用self.\uuuu index=self与在定义文件室本身时使用writing Room.\uuuu index=Room相同,但在每次复制相同/类似代码时都会有所帮助:
如果我们已定义Room.floor=地毯,则printroom1.floor的结果将是预期的地毯。room1.floor的值为nil,然后Lua将在room1的元表中查找_索引,在该索引中,它发现该房间可能包含它所查找的内容。事实上,Room.floor是有定义的,这就是Lua所看到的答案
总结
您还可以设置一个元文件,并使用_index方法来定义您希望执行的对象。我认为这可能会提高内存效率,因为您没有为同一类的每个对象分别定义每个函数
另外,如果您想在执行类似于room1:intersectsroom1的操作时使用Room:Intersects give false,只需添加self~=other。只有当self和other是完全相同的表时,该操作才会成功,即使房间的所有值都相同,它们也不会相等并相互相交。正如Dahk所说,您定义的房间表也是作为新房间对象返回的房间表。 房间:方法。。。是Room.methodRoom 当您使用速记时,Lua提供的self变量包含对Room的引用,因此当您键入Room:new5、6、3、3时,Lua读取的是Room.newRoom,5、6、3、3,其中self=Room。当我们让self.width=5时,发生的是Room.width=5,而这不是我们想要发生的 为了解决这个问题,我们需要在每次调用Room:new时创建一个新对象。我们创建一个名为obj的新表,然后将值存储在该表中
function Room:new(width, height, x, y)
local obj = {
Width = width,
Height = height,
X = x,
Y = y,
Left = x,
Right = x + width,
Top = y,
Bottom = y + height,
}
return obj
end
这很好,我们现在可以创建房间了。但当我们尝试执行room1:Intersect时,我们得到了一个错误:方法Intersects未定义。我们可能定义了一个新房间,但这个房间只不过是一张简单的桌子。这就是元表的用武之地。简言之,元表定义了表的行为。在我们的例子中,我们希望它包含一个值,以便Lua在原始列表中找不到值或方法时可以查看。有关元表的更多信息,请参见
让我们看一个例子:
我
如果每个房间的地板都是一样的,我们可以把这个地板复制给每个孩子,或者让room.floor=地毯,当有人问我们某个房间的地板是什么时,我们就回到这个房间。回到这里,我们使用元表和方法。这个方法是Lua查找它找不到的值的地方
function Room:new(width, height, x, y)
local obj = {
...
}
setmetatable(obj, self) -- self here is equal to Room
self.__index = self
return obj
end
我们再次创建对象,其中包含要分别为每个房间存储的所有值。其次,我们让Room成为obj的元表。第三行告诉我们,当找不到任何方法时,应该使用房间表。
在创建对象期间使用self.\uuuu index=self与在定义文件室本身时使用writing Room.\uuuu index=Room相同,但在每次复制相同/类似代码时都会有所帮助:
如果我们已定义Room.floor=地毯,则printroom1.floor的结果将是预期的地毯。room1.floor的值为nil,然后Lua将在room1的元表中查找_索引,在该索引中,它发现该房间可能包含它所查找的内容。事实上,Room.floor是有定义的,这就是Lua所看到的答案
总结
您还可以设置一个元文件,并使用_index方法来定义您希望执行的对象。我认为这可能会提高内存效率,因为您没有为同一类的每个对象分别定义每个函数
另外,如果您想在执行类似于room1:intersectsroom1的操作时使用Room:Intersects give false,只需添加self~=other。只有当self和other是完全相同的表时,才能成功,即使房间的所有值都相同,它们也不会相等并相互相交