lua 中的 bug 还是我不知道的特性?

我正在教一个朋友 lua,他拿着这段代码来考验我:

a = {name = "aaa"}

function a:new()
  self.x = "sss"
  o = {}
  setmetatable(o, self)
  self.__index = self
  return o
end

function a:some()
  return "[ " .. self.name .. " ]"
end

b = a:new()
print(b:some())
print(b.x)

代码的输出结果是

[ aaa ] sss

这两个值都应该是不可能的,因为它们都没有在 a:new 中被设置为 o 的属性。

经过一些调试,我发现一些有趣的事情:

a = {name = "aaa", x = "sss"}

function a:new()
  o = {}
  print(o.x, self.x)
   -- nil sss
  setmetatable(o, self)
  print(o.x, self.x, o, self, self.__index, o.__index)
   -- nil sss table: 0x1001280 table: 0x1001320 table: 0x1001320 nil
  self.__index = self
  print(o.x, self.x, o, self, self.__index, o.__index)
   -- sss sss table: 0x1001280 table: 0x1001320 table: 0x1001320 table: 0x1001320
  return o
end

注意第三个 print,它返回了 self.x 值,但它是从没有与 self 任何关系的 o 中调用的,这怎么可能?

点赞
用户5675002
用户5675002

你在元表中将表 a 设置为所有通过 a:new() 创建的表的 __index 字段。当在表 b 中检查不存在的字段时,该值也将在表 a 中查找。这就是为什么你可以在表 b 中找到字段 xname,即使你没有显式赋值。

2017-11-02 21:05:16