和元表

问题描述:

我学习和Lua的面向对象编程。我无法理解在实例的__index字段中分配表格并为实例设置metatable之间的功能差异。我回顾了官方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类作为其metatable,那么在这种情况下真正使用metatables有什么用处?为什么Lua允许类为其实例的metatables?

从我的理解,元表应该是只包括元方法(__newindex,__index,__add等)表。但这个例子有__index为Account类的领域,它通过这一点,是不是元表并没有一个元表分配给它使得分配查找另一元表,如果是有道理的。

在此先感谢。

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

既然是有些多余在构造函数中定义__index,你经常会看到这样的例子:

Account = {} 
Account.__index = Account 

function Account:new (o) 
    o = o or {} 
    setmetatable(o, self) 
    return o 
end 

我无法理解的__index领域分配表之间的功能差异一个实例并为该实例设置一个metatable。

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

从我的理解中,metatables应该是仅由metamethods组成的表(__newindex,__index,__add等)。

上有什么可元表包含没有限制,但是一个表需要定义至少一个元方法的元表使用时有任何效果。

Metamethods基本上提供操作符重载。这意味着metatables可以为其他表定义行为。 __index是面向对象的真正重要的元方法,因为这就是我们如何使用实例来访问类中定义的方法和变量。

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

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

+0

谢谢您的快速回答。关于分配“帐户.__索引=帐户”,我是否正确地说这只在我期望用户创建帐户实例时才需要,否则,分配不需要? – bladematthewslp

+0

是的。我不知道有任何其他理由要这样做。 – luther

+1

好的,谢谢!这有助于很多。我现在终于明白了。我来自C++/Java/C#背景,所以Lua的面向对象设计版本需要对思维方式进行一些调整。 – bladematthewslp