4

我使用 Lua 作为我的 C++ 应用程序的数据描述语言。我有一堆使用 SLB 2.0 绑定到 Lua 的 C++ 类。我绑定了诸如“SetPos”或“SetName”之类的方法。我使用以“pos”或“name”作为键值的表​​来指定位置或名称(例如)。我希望能够获取密钥,添加“set”,然后调用该方法(如果存在)(可能不存在)。那可能吗?如果是这样,有什么建议吗?

我知道我可以让我的绑定方法小写,但我宁愿让它们与它们绑定的方法相同(尽管这可能是我的后备)。我可以尝试根据我的命名标准构建方法名称,但不区分大小写不太容易出错。

我觉得应该有一个棘手的 Lua 可以使用元表解决这个问题,但我自己无法解决这个问题。

有什么建议么?

谢谢!

4

1 回答 1

5

不区分大小写并不是 Lua 真正处理的事情。所有表查找和局部变量访问最终都是区分大小写的字符串比较。

最好的解决方案是接受您正在处理一个区分大小写的系统,就像 C++ 一样,然后处理它。

但是,如果你真的想这样做,你可以这样做。最简单的方法是将名称的所有可能的大小写排列放在函数表中。所以你的函数表会有这个:

["setname"] = theFunction,
["Setname"] = theFunction,
["sEtname"] = theFunction,
["SEtname"] = theFunction,
...

您当然可以使用一个函数自动执行此操作,该函数采用表中的每个名称并根据大小写排列复制其数据。

一个更复杂但更容易使用的机制是使用__index__newindex元方法以及空表技巧。

function CreateCaseInsensitiveTable()
  local metatbl = {}

  function metatbl.__index(table, key)
    if(type(key) == "string") then
      key = key:lower()
    end

    return rawget(table, key)
  end

  function metatbl.__newindex(table, key, value)
    if(type(key) == "string") then
      key = key:lower()
    end

    rawset(table, key, value)
  end

  local ret = {}
  setmetatable(ret, metatbl)
  return ret
end

您无需使用 {} 创建表,而是使用此函数调用创建表。该表应该正常运行(尽管显然成员访问会稍微慢一些)。

于 2012-02-01T20:58:34.960 回答