【问题标题】:Lua/Luajit: Indexing and named method at the same time?Lua/Luajit:同时索引和命名方法?
【发布时间】:2019-04-02 16:50:04
【问题描述】:

Lua PILLuajit FFI tutorial 在元表中给出了__index 的两种用法。

一个用于像obj[123]这样的索引,例如,

__index = function (self, k) return self._data+(k-self._lower)

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

__index = { area = function(a) return a.x*a.x + a.y*a.y end, },

然后我们可以像obj:area()一样进行函数调用。

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

【问题讨论】:

  • 是的。您需要检查type(k) 并执行适当的操作(数字键操作或字符串键操作)。
  • 是的,这是关键,如果与 Azdle 给出的答案相结合,可能会更有效,即在另一个元表中查找字符串键操作。谢谢你,Egor Skriptunoff。

标签: lua ffi luajit


【解决方案1】:

答案,就像 Lua 中特别有趣的代码一样,是更多的元表。

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

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"

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


还有另一个可能更直接的答案:使用您的 __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 上测试。

【讨论】:

  • 谢谢阿兹德尔。这解决了我的问题。我添加了t={1,2,3} 之类的代码,然后可以使用您的代码访问t[1] 之类的内容以及其他命名方法。
猜你喜欢
  • 2017-07-22
  • 2013-09-25
  • 1970-01-01
  • 2021-12-17
  • 2012-11-24
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多