【问题标题】:why does first example constructor set `__index` on `self`?为什么第一个示例构造函数在 `self` 上设置 `__index`?
【发布时间】:2021-03-29 14:34:23
【问题描述】:

我刚开始看Lua,我在看introductory Lua example for "classes"

Account = {balance = 0}

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

我不明白为什么构造函数不只是

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

如果能帮助我理解这一点,我将不胜感激。

编辑:

@Egor 观察到第二种方法会创建太多的元表。好的,我明白了(事实上,这很明显)。但是第一种方法仍然感觉很奇怪(例如,它反复将__index 设置在Account 上)。也许这样的事情会同时满足这两个反对意见?

Account = {balance = 0}
Account_meta = {__index = Account}

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

【问题讨论】:

  • 在第二个示例中,您将为每个对象创建新的元表。太耗内存了。
  • @EgorSkriptunoff 谢谢。你可以评论我的编辑吗?
  • 元表可能和类本身是同一个表,这样会多保存一个表。
  • @EgorSkriptunoff 当然。但是假设我不是在一个每个内存字节都很重要的系统上工作;还有其他理由不使用第三种方法吗?谢谢!
  • 第三种方法绝对可以。

标签: lua lua-table


【解决方案1】:

我相信这种方法的唯一原因是将其与next section 中的继承联系起来。

那里的继承实现使用SpecialAccount = Account:new() 创建SpecialAccounts 的原型,然后使用instance = SpecialAccount:new() 创建SpecialAccount 的新实例。

如果我们希望这种方法能够正常工作,这两个调用之一必须将SpecialAccount.__index 设置为SpecialAccount。假设我们希望__index 只设置在原型/元表/类上,它必须是第二个。这需要我们在每个对象创建过程中重复一项分配,但我想这并不重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2012-03-09
    • 2021-09-30
    • 2022-08-11
    相关资源
    最近更新 更多