Lua 元表变量声明



我不知道该怎么命名这个问题,因为我对正在发生的事情还不够了解。随意编辑(

请考虑下面的代码。

函数对象:新((    o = o 或 {        x = 0    }    设置元表(O,自我(    self.__index = 自我    self.y = 0返回 o结束表 = 对象:新((

稍后变量(o.x 和 self.y(之间有什么区别?

如果我print_r变量table,则只返回 x。但是,可以访问table.xtable.y。这让我意识到两者之间是有区别的。

有人可以解释一下区别是什么以及将变量放在不同位置的原因是什么?

稍后变量(o.x 和 self.y(之间有什么区别?

您这里有两张表, object o

object:new内部,self指的是表object。所以self.y是表中的字段object.

o 是在每次调用 object:new 中创建的新表。 o.x是表中的字段 o

o表只有一个条目:o["x"] ,因此当您迭代表中的条目时(如print_r一样(,这就是您将看到的全部内容。

那么o.y为什么要给你一个价值呢?因为您将表object设置为 o 的元表,并且该元表设置了__index字段,所以当索引尝试在 o 上失败时,Lua 将通过 o元表重试(如果它设置了__index(。

一些代码可能会使这一点更清晰:

o = { x = 33 }
print(o.x, o.y) --> 33 nil
-- let's give o a metatable
mt = { y = 20 }
setmetatable(o, mt)
-- we've given o a metatable, but that metatable doesn't have an __index member set
print(o.y) --> nil
-- metatable `handlers` are normally functions that handle events
-- here we create a handler for indexing a table if the key doesn't exist in the table:
mt.__index = function(t,k)
  print("An attempt was made to index table", t, "with the key", k)
  return 5150
end
-- we've given o's metatable a handler for indexing which always returns 5150
print(o.x) --> 33
print(o.y) --> 5150
print(o.z) --> 5150
print(o.donut) --> 5150
-- note that Lua has a "rawget" function, which bypasses the metatable mechanics
print(rawget(o,'x')) --> 33, we get a value, because o actually contains "x"
print(rawget(o,'y')) --> nil, back to nil, because the metatable is being ignored
-- the __index metatable handler is special. Instead of providing a function
-- to handle missing key events, you can give it a table. If an index attempt fails,
-- it will try again in the __index table
mt.__index = mt -- we could have used a third table here, but mt has the y entry we want
-- we've changed the metatable handler, so now we'll get 777
print(o.y) --> 777
-- changes to the metatable are reflected in any object using it as metatable
mt.__index.y = 999
print(o.y) --> 999
-- now we give `o` it's OWN "y" entry, so the metatable handler will no longer be invoked
o.y = 2112
print(o.y) --> 2112
print(rawget(o, 'y')) --> o really owns this "y" entry
print(mt.__index.y) --> 999, the metatable was untouched by our write to o.y

最新更新