__index字段和metatable中的表之间的差异

时间:2017-10-14 21:09:19

标签: lua

我正在用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,如果这是有意义的。

提前致谢。

1 个答案:

答案 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是一个表。它也可以是一个函数)。