在lua中编程,对象

ano*_*non 6 lua

示例代码:

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

取自:

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

目的是什么:

self.__index = self
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*ley 6

正如其他人所说,self(Account表)被用作分配给使用创建的对象的元表new.当在"o"中找不到字段时,稍微简化(在提供的链接上提供更多信息),它会转到"帐户"表,因为o的metatable表示转到帐户(这就是做什么__index).

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

Account.__index = Account
Run Code Online (Sandbox Code Playgroud)

它也会起作用.

更长的故事是,如果一个对象o具有metatable,并且metatable具有__index字段集,那么失败的字段查找o将用于__index查找字段(__index可以是表或函数).如果o设置了字段,则不会转到其metatable的__index函数来获取信息.不过,我再次鼓励您阅读上面提供的链接.


小智 6

Lua 文档对这个细节有些含糊,这里的许多答案要么与 Lua 文档相呼应,要么没有彻底解释这个令人困惑的花絮。

该行self.?index = self纯粹是为了新创建的对象的利益而存在o;它对 没有意义或功能影响Account

?index字段仅在元表的上下文中具有特殊含义;因此self.?index只是一个普通的旧常规字段Account。但是,当Account用作 for 的元表时o,该?index字段“变成”了 for 的元方法o。(因此,字段 forAccount是 .的元方法o。)

当你把这两个陈述结合起来......

(1) setmetatable(o, self)
(2) self.?index = self

...您正在使用Account的元表的o上线(1),并设置?index元方法的oAccount就行(2)。(ON LINE(2),你还设置“普通老式场”__indexAccountAccount。)做的有用的方面self.?index = self不是的设置?index现场Account,而是的设置?index元方法进行o

以下在功能上是等效的:

    setmetatable(o, self)
    getmetatable(o).?index = self