__index字段中的表和元表之间的区别

bla*_*slp 6 lua

我正在使用 Lua 学习面向对象编程。我无法理解在实例的 __index 字段中分配表和为实例设置元表之间的功能差异。我查阅了官方Lua的参考手册,但我并没有完全理解其中的区别。例如,要创建 Account 类的实例,它将 Account 类 (self) 的 __index 字段设置为其自身,然后将该实例的元表设置为 Account 类。

function Account:new (o)
  o = o or {}
  self.__index = self
  setmetatable(o, self)
  return o
end
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?在这种情况下,为什么帐户要为其自身设置自己的索引?在这种情况下,如果实例“o”只是使用 Account 类作为其元表,那么真正的元表有什么用?为什么 Lua 允许类作为其实例的元表?

根据我的理解,元表应该是仅由元方法(__newindex、__index、__add 等)组成的表。但该示例将 __index 作为 Account 类的字段,此时它不是元表,也没有分配给它的元表,因此分配会查找另一个元表(如果有意义的话)。

提前致谢。

lut*_*her 7

在示例中,Account是元表,o是实例。由于Account被用作类,因此它需要一个__index字段来定义常规方法。该__index字段是在构造函数中定义的,因为调用构造函数的行为意味着该Account字段被用作类。

由于在构造函数中定义有些多余__index,因此您经常会看到如下示例:

Account = {}
Account.__index = Account

function Account:new (o)
  o = o or {}
  setmetatable(o, self)
  return o
end
Run Code Online (Sandbox Code Playgroud)

我无法理解在实例的 __index 字段中分配表和为实例设置元表之间的功能差异。

您通常不会放入__index实例。(尽管在 PiL 示例中,任何对象都可能被用作另一个类。请谨慎使用。)为实例设置元表是将元方法应用于该实例的。

根据我的理解,元表应该是仅由元方法(__newindex、__index、__add 等)组成的表。

元表可以包含的内容没有限制,但是表需要定义至少一种元方法才能在用作元表时发挥作用。

元方法本质上提供运算符重载。这意味着元表可以定义其他表的行为。__index是 OOP 中真正重要的元方法,因为这就是我们如何使用实例来访问类中定义的方法和变量。

为什么元表__index通常指向自身?因为否则,我们需要另一个表来保存常规方法。对于简单的 OOP 框架,让一个表完成这两项工作会更容易。

简短的回答:元表定义实例的元方法。__index是将字段访问路由到另一个表的元方法(如果__index是表。它也可以是函数)。