Lua/Luajit:同时索引和命名方法?

Lua/Luajit:同时索引和命名方法?,lua,ffi,luajit,Lua,Ffi,Luajit,and给出了元表中\uuu索引的两种用法 foo = function() print("foo") end bar = function(_, key) return function() print(string.format("bar: %s", key)) end end mmt = { __index = bar } mti = { foo = foo } mt = { __index = mti } t = {} setmetatable(mti, mmt

and给出了元表中
\uuu索引
的两种用法

foo = function()
  print("foo")
end

bar = function(_, key)
  return function()
    print(string.format("bar: %s", key))
  end
end

mmt = { __index = bar }
mti = { foo = foo }
mt = { __index =  mti }
t = {}

setmetatable(mti, mmt)
setmetatable(t, mt)

t.foo()  -- prints: "foo"
t.bar()  -- prints: "bar: bar"
t.baz()  -- prints: "bar: baz"
一种是用于索引,如obj[123],例如

\u索引=函数(self,k)返回self.\u数据+(k-self.\u下)

另一种用法是定义命名方法,如教程中所述

\uuu index={area=function(a)返回a.x*a.x+a.y*a.y end,},

然后我们可以进行类似于
obj:area()
的函数调用


我可以同时做这两件事吗,例如,直接索引和命名方法?

答案是更多的元表,这与Lua中特别有趣的代码的答案一样

当您的
\u索引
元方法实际上是一个表时,Lua只需对给定表进行标准表访问。这意味着您可以在元表上设置元表。然后您可以在此“元元表”上设置一个_索引元方法

这样,当您尝试访问两个表中都不存在的字段时,lua将首先尝试访问顶级表,该顶级表将访问第一个元表,然后在第二个元表中调用您的元方法

foo = function()
  print("foo")
end

bar = function(_, key)
  return function()
    print(string.format("bar: %s", key))
  end
end

mmt = { __index = bar }
mti = { foo = foo }
mt = { __index =  mti }
t = {}

setmetatable(mti, mmt)
setmetatable(t, mt)

t.foo()  -- prints: "foo"
t.bar()  -- prints: "bar: bar"
t.baz()  -- prints: "bar: baz"

还有另一个可能更直截了当的答案:使用
\u index
元方法检查另一个表中的命名字段:

foo = function()
  print("foo")
end

f = { foo = foo }

bar = function(_, key)
  if f[key] then return f[key] end
  return function()
    print(string.format("bar: %s", key))
  end
end

mt = { __index =  bar }
t = {}

setmetatable(t, mt)

t.foo()  -- prints: "foo"
t.bar()  -- prints: "bar: bar"
t.baz()  -- prints: "bar: baz"

在Lua 5.3上测试。

是。您需要检查
键入(k)
并执行相应的操作(对于数字键的操作或对于字符串键的操作)。是的,这就是键,如果与Azdle给出的答案结合使用,可能会更干净,也就是在另一个元表中查找字符串键操作。谢谢你,伊戈尔·斯克里普托诺夫,谢谢你,阿兹德尔。这解决了我的问题。我添加了
t={1,2,3}
等代码,然后可以使用您的代码访问
t[1]
等内容以及其他命名方法。