【问题标题】:Lua reference table inside metatable元表中的 Lua 引用表
【发布时间】:2018-11-14 04:43:52
【问题描述】:

我现在有一个非常令人费解的设置。我有一个常规函数,它在“字符串”和“数字”键下返回一个包含函数的表:

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()。具体来说:

  1. 如果使用字符串str调用v,则返回v["string"](str)的结果
  2. 如果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 = function(t,x) return t[type(x)](x) end
  • @EgorSkriptunoff 刚刚想通了!谢谢!将其发布为答案,我会接受。

标签: oop lua metatable


【解决方案1】:

传递给__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

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多