[英]Making sense of OOP in Lua
I do most of my programming in Python, and I use OOP practices for most of my projects. 我在Python中编写了大部分编程,并且在大多数项目中使用OOP实践。 I recently started taking a look at the Love2D game library and engine. 我最近开始看看Love2D游戏库和引擎。 I managed to get some things configured, and then thought about making a GameObject class. 我设法配置了一些东西,然后考虑制作一个GameObject类。 But, what's this? 但是,这是什么? Lua doesn't have classes! Lua没有课程! It has tables, and metatables, and other such things. 它有表格,元表和其他类似的东西。 I'm having a lot of trouble making heads or tails of this even after reading the documentation several times over. 即使在多次阅读文档后,我仍然遇到很多麻烦。
Consider the following example: 请考虑以下示例:
catClass = {}
catClass.__index = catClass
catClass.type = "Cat"
function catClass.create(name)
local obj = setmetatable({}, catClass)
obj.name = name
return obj
end
cat1 = catClass.create("Fluffy")
print(cat1.type)
cat2 = catClass.create("Meowth")
cat1.type = "Dog"
print(cat1.type)
print(cat2.type)
print(catClass.type)
The output of this is as follows: 输出如下:
Cat
Dog
Cat
Cat
What I do not understand is why changing cat1.type to "Dog" does not cause identical changes in cat2 and catClass. 我不明白为什么将cat1.type更改为“Dog”不会导致cat2和catClass发生相同的变化。 Does setting a metatable create a copy of the table? 设置元表是否会创建表的副本? Google did not provide useful results (there are very few good Lua explanations). 谷歌没有提供有用的结果(很少有很好的Lua解释)。
When you index a table and a key does not exist then Lua will look to see if a metatable exists for the table. 当您索引表并且键不存在时,Lua将查看该表是否存在metatable。 If one does then it will use the __index
key of that metamethod to re-index your key. 如果有,那么它将使用该元方法的__index
键重新索引您的密钥。
When you created cat1
it inherited the catClass
metatable. 当你创建cat1
它继承了catClass
metatable。 Then when you indexed type
it will see that cat1
does not have a table entry called type
and thus looks to the metatable to find it. 然后,当您索引type
,它将看到cat1
没有名为type
的表条目,因此查找metatable以查找它。
Then you set type
on cat1
to Dog
, which only sets the table key of cat1
itself, not the metatable. 然后,设置type
上cat1
到Dog
,只设置的表密钥cat1
本身,而不是元表。 That is why when you index cat1
again for type
you get Dog
and not Cat
. 这就是为什么当你指数cat1
再次type
你Dog
,而不是Cat
。
If you go to http://www.lua.org/ there is documentation and some older copies of the Programming in Lua, written by the authors of Lua itself. 如果你去http://www.lua.org/,那里有Lua编写的文档和Lua编程的一些旧版本。
See the setmetatable
documentation - the table returned is the table specified in the first argument. 请参阅setmetatable
文档 - 返回的表是第一个参数中指定的表。
This is a different table for each invocation of create
(thanks to {}
) and each new table is also distinct from the metatable used. 对于create
每次调用,这是一个不同的表(感谢{}
),每个新表也与使用的元表不同。 No copy was made, but rather a new table was created which is then "linked" 1 to the metatable. 没有复制,而是创建了一个新表,然后将其“链接” 1到metatable。
Thus there are three different tables in the above - cat1
(with mt catClass), cat2
(also with mt catClass) and catClass
itself. 因此,上面有三个不同的表 - cat1
(使用mt catClass), cat2
(也使用mt catClass)和catClass
本身。 Altering cat1
, as done, therefor has no effect on the other two tables. 改变cat1
,就像完成一样,因此对其他两个表没有影响。
1 See Lua Metatables Tutorial ; 1参见Lua Metatables教程 ; the use of the __index
presented in the metatable effectively emulates JavaScript's [prototype] resolution. 使用metatable中提供的__index
有效地模拟了JavaScript的[原型]分辨率。
When you look up a table with a key , regardless of what the key is, and a value hasn't been assigned for that key .. Lua will look for an
__index
key in the table's metatable .. If__index
contains a table, Lua will look up the key originally used in the table belonging to__index
. 当您使用键查找表时 ,无论键是什么, 并且没有为该键分配值 .Lua将在表的metatable中查找__index
键。 如果__index
包含表,Lua将查找最初在属于__index
的表中使用的密钥。
However, __index
has no affect on assigning a new index to one of the tables - the particular table is just modified as normal. 但是, __index
index对于为其中一个表分配新索引没有任何影响 - 特定表只是正常修改。 (The tutorial also goes on to explain __newindex
, if such write-through behavior is desired.) (如果需要这样的直写行为,本教程还会继续解释__newindex
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.