简体   繁体   English

理解Lua中的OOP

[英]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. 然后,设置typecat1Dog ,只设置的表密钥cat1本身,而不是元表。 That is why when you index cat1 again for type you get Dog and not Cat . 这就是为什么当你指数cat1再次typeDog ,而不是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.

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