oop - 元表中的 Lua 引用表
问题描述
我现在有一个非常令人费解的设置。我有一个常规函数,它在键“string”和“number”下返回一个包含函数的表:
function defGeneric()
local function funcNumber(a)
return 2*a^2
end
local function funcString(a)
return a.." - test"
end
local returnTable={}
returnTable["number"]=funcNumber
returnTable["string"]=funcString
return returnTable
end
这很好用。但是我现在要做的是使该函数返回的表可调用。为了说明,假设我们有v=defGeneric()
. 具体来说:
- 如果
v
用字符串调用str
,返回结果v["string"](str)
- 如果
v
用数字调用n
,则返回结果v["number"](n)
这显然是元表的工作,所以我可以(在我的函数中)添加代码来设置元表:
local metaTable = {
__call = function (...) -- "call" event handler
return
end
}
setmetatable(returnTable,metaTable)
但我不知道在返回声明之后我会放什么。我不认为我可以引用 returnTable,因为这个表会这样调用:
v=defGeneric()
v("test")
而且我需要引用v
的“字符串”函数(一个程序中当然可以有多个 defGeneric() 表)。
我认为这里的答案可能是一些self
技巧,但我无法理解如何。如何从元表中引用元表的表?
解决方案
传递给__call
函数的第一个参数是它被调用的表,在这种情况下是从函数返回的表。您可以使用type(a)
将参数的类型作为字符串获取,因此您可以执行以下操作:
function defGeneric()
local result = {
['number'] = function(a) return 2*a^2 end,
['string'] = function(a) return a.." - test" end
}
setmetatable(result, {
__call = function(t,a)
local f = t[type(a)]
if f == nil then return "No handler for type "..type(a) end
-- alternate:
-- if f == nil and t['string'] ~= nil then return t['string'](tostring(a)) end
return f(a)
end
})
return result
end
local def = defGeneric()
print("string: "..tostring(def('sample string')))
print("number: "..tostring(def(5)))
print("table: "..tostring(def({})))
print("boolean: "..tostring(def(1 > 5)))
输出
string: sample string - test
number: 50.0
table: No handler for type table
boolean: No handler for type boolean
交替输出
string: sample string - test
number: 50.0
table: table: 0x18537e0 - test
boolean: false - test
推荐阅读
- arraylist - 我如何计算 wxmaxima 中列表的成员?
- javascript - Onclick 按钮仅在第一个列表中有效
- azure - Azure WVD 部署域加入失败
- css - React 是否支持内联样式的 cmyk 颜色定义?
- php - 在php中使帖子永久化
- xml - 使用递归 XML 模式进行验证未在嵌套元素中找到预期的错误
- javascript - 在 Batch-HTA 脚本中添加编程按钮
- c# - Okta:无法从“System.String”获取配置
- java - 在 Micronaut 中使用 @Client 接口时如何处理错误
- c++ - 如何获得连续提供数据以输出一位整数值的输入