我正在用Lua学习面向对象的编程。我无法理解在实例的__index字段中分配表和为实例设置元表之间的功能差异。我查看了官方Lua的参考手册,但我没有完全掌握其中的差异。例如,要创建Account类的实例,它会将Account类(self)的__index字段设置为自身,然后将实例的metatable设置为Account类。
function Account:new (o)
o = o or {}
self.__index = self
setmetatable(o, self)
return o
end
这里发生了什么?在这种情况下,为什么Account将自己的索引设置为自己?如果实例'o'仅使用Account类作为其元表,那么在这种情况下使用真正的元表会有什么用?为什么Lua允许类为其实例进行元化?
根据我的理解,metatables应该是仅由metamethods(__ newindex,__ index,__ add等)组成的表。但是该示例将__index作为Account类的一个字段,到目前为止,该字段不是metatable,并且没有为其分配metatable,以便分配查找另一个metatable,如果这是有意义的。
提前致谢。
答案 0 :(得分:2)
在示例中,Account
是metatable,o
是实例。由于Account
被用作类,因此需要__index
字段来定义常规方法。 __index
字段在构造函数中定义,因为调用构造函数的行为意味着Account
被用作类。
由于在构造函数中定义__index
有些多余,因此您经常会看到如下示例:
Account = {}
Account.__index = Account
function Account:new (o)
o = o or {}
setmetatable(o, self)
return o
end
我无法理解在实例的__index字段中分配表和为实例设置元表之间的功能差异。
您通常不会将__index
放入实例中。 (尽管在PiL示例中,任何对象都可能被用作另一个类。请谨慎使用。)为实例设置metatable是将metamethods应用于该实例的原因。
根据我的理解,metatables应该是仅由metamethods组成的表(__ newindex,__ index,__ add等)。
对于metatable可以包含的内容没有任何限制,但是当用作metatable时,表需要定义至少一个metamethod以产生任何效果。
Metamethods主要提供运算符重载。这意味着元表可以定义其他表的行为。 __index
是OOP非常重要的元方法,因为我们可以使用实例来访问类中定义的方法和变量。
为什么metatable的__index
通常指向自己?否则,我们需要另一个表来保存常规方法。对于简单的OOP框架,让一个表执行这两项工作更容易。
简短回答:metatable为实例定义了元方法。 __index
是将字段访问路由到另一个表的元方法(如果__index
是一个表。它也可以是一个函数)。