代码之家  ›  专栏  ›  技术社区  ›  anon

在lua中编程,对象

lua
  •  5
  • anon  · 技术社区  · 15 年前

    示例代码:

    function Account:new (o)
      o = o or {}   -- create object if user does not provide one
      setmetatable(o, self)
      self.__index = self
      return o
    end
    

    摘自:

    http://www.lua.org/pil/16.1.html

    目的是什么:

    self.__index = self
    

    线路?为什么每次创建对象时都要执行它?

    5 回复  |  直到 12 年前
        1
  •  5
  •   David Haley    15 年前

    正如其他人所说, self (the Account 表)用作指定给使用 new . 稍微简化一下(在提供的链接中提供更多信息)当在“o”中找不到字段时,它会转到“account”表,因为o的元表说要转到account(这就是 __index )。

    但是,不需要每次创建对象时都执行它。你可以很容易地把这个放在某个地方:

    Account.__index = Account
    

    它也会起作用的。

    有点长的故事是如果一个物体 o 有一个元表,该元表有 _索引 现场设置,然后 失败 字段查找打开 o 将使用 _索引 找到那块地( _索引 可以是表或函数)。如果 o 已设置字段,则不转到其元表的 _索引 函数获取信息。不过,我再次鼓励您阅读上面提供的链接。

        2
  •  4
  •   Liam    14 年前

    lua文档在这个细节上有点模糊,这里的许多答案要么与lua文档相呼应,要么没有完全解释这个令人困惑的小道消息。

    线路 self._index = self 只是为了新创建的对象的利益, o ;对 Account .

    这个 _index 字段仅在元表上下文中具有特殊意义;因此 self._index 只是一个普通的老规则字段 帐户 . 但是,当 帐户 用作的元表 o , the 索引 字段“成为”的元方法 o . (那么一块地是用来干什么的? 帐户 是的元方法 o )

    当你把这两种说法结合起来…

    (1)    setmetatable(o, self)
    (2)    self._index = self
    

    …你在用 帐户 作为的元表 o 在线(1)并设置 指数 元方法 o 帐户 在线(2)。(在第(2)行中,您还设置了“普通旧字段” __index 在里面 帐户 帐户 )所以 self.index=自我 不是 指数 字段 帐户 ,而是设置 指数 元方法 o .

    以下功能等同:

        setmetatable(o, self)
        getmetatable(o)._index = self
    
        3
  •  3
  •   Judge Maygarden    13 年前

    lua不是一种面向对象的语言,但它拥有编写面向对象代码的所有功能。但是,它是在 prototyping 时尚A LA JavaScript . 不再显式创建类,而是创建一个原型对象,然后克隆以创建新实例。

    这个 __index 当表中不存在键时,调用metamethod对表的读取访问执行键查找。所以, self.__index = self 基本上允许继承 Account 在中创建的新“实例”的“类” o = o or {} setmetatable(o, self) 线。

    另见:

        4
  •  0
  •   Puppy    15 年前

    它们用于重新定向表访问(local y=table[key]),这些访问也用于方法调用。在上述行中,对象o将尝试访问重新定向到当前对象自身的密钥,轻松地继承所有成员函数。也可能是数据变量,这取决于那个索引到底是什么以及它是如何工作的。

        5
  •  0
  •   gunr2171    12 年前

    创建对象(只是表)与lua有很大不同。 基本思想是创建一个包含所有实例通用属性(函数和值)的常规表。这个表,我将调用catforcommonattributes表。

    如果在表中引用某个属性,而lua找不到该属性,则可以告诉lua在其他地方查找该属性。我们希望lua在猫身上寻找共同的属性。元表回答了这一需求。稍后将详细介绍这一工作原理。

    我们还需要cat中的方法能够使用实例值。 自我 需要的答案。以这种方式调用表函数(方法)时: tableName:methodName() ,lua会自动将对table对象的引用作为第一个参数。此参数的名称是self。即使该方法位于cat中,self也将引用特定的调用对象实例表。

    假设我们有一只猫叫车。

    metaCar = { __index = Car }  
    -- this table will be used as the metatable for all instances of Car  
    -- Lua will look in Car for attributes it can't find in the instance
    

    例如:

    -- instance table is called mustang    
    -- setmetatable(mustang, metaCar)
    

    下面是一个通用函数,用于创建新的实例对象并为其设置元表。如果cat有一个构造函数(init),它也会被执行。

    function newObj(metatable)  
    ..obj = {}      -- create new empty instance object  
    ..setmetatable(obj, metatable) –- connect the metatable to it  
    ..if obj.init then  -- if the CAT has an init method, execute it  
    ....obj:init()  
    ..end  
    ..return obj  
    end