1

路亚 5.1.4

例如:

bar = {}
bar.name = 'test'
bar['123.com'] = function(self) print(self.name) end

我不能调用如下方法:

bar:['123.com']()
stdin:1: '<name>' expected near '['

虽然下面的作品:

bar['123.com'](bar)

但我这有点难看。这种情况有语法糖吗?

或者如果真的做不到,Lua 团队会在未来添加这个语法吗?

还是他们故意这样做的?

4

6 回答 6

7

不,我们不能像你想要的那样调用方法。您假设仅按以下语法调用该方法。

bar['123.com'](bar)
于 2012-04-18T04:17:50.767 回答
4

只需创建一个不以数字开头的别名并使用它。

bar.name123 = bar['123name']

bar:name123()
于 2012-04-19T08:13:02.857 回答
2

没有人知道 Lua 维护者会在未来的版本中添加什么(他们非常守口如瓶),但我的猜测是他们不太可能在没有被询问的情况下添加它——而且我从未见过这样的请求Lua 邮件列表中的一件事......

不过,我的直觉是,这个功能似乎很模糊:人们真正想要调用具有“奇怪”名称的方法的频率是多少?鉴于此,并且“解决方法”确实一点也不差,尚不清楚是否值得增加实现的复杂性以支持这样的功能(除非它完全微不足道)。

如果你想尝试询问,你应该将它发布到 Lua 邮件列表,这是大多数此类讨论发生的地方: lua-l@lists.lua.org

于 2012-04-18T23:59:32.897 回答
2

您可能需要考虑以下内容(您可以在http://www.lua.org/cgi-bin/demo在线测试):

bar = {}
bar.name = 'test'
bar['123.com'] = function(self) print(self.name) end

bar2 = setmetatable({}, {
  __index = function(t, key)
    return function(...)
      return bar[key](bar, ...)
    end
  end
})

bar2['123.com']()
-- output: test

您也可以将bar自身更改为以类似方式运行,只是您必须在分配任何值之前执行此操作 - 例如:

bar = {}

local privatekey = {}
setmetatable(bar, {
  __index = function(t, key)
    local value = rawget(t, privatekey)[key]
    if type(value) ~= 'function' then
      return value
    end
    return function(...)
      return value(t, ...)
    end
  end,
  __newindex = function(t, key, value)
    rawset(t, privatekey, rawget(t, privatekey) or {})
    rawget(t, privatekey)[key] = value
  end
})

bar.name = 'test'
bar['123.com'] = function(self) print(self.name) end
bar['123.com']()
-- output: test
于 2012-04-19T14:30:09.357 回答
1

您可以使用闭包

bar = {}
bar.name = 'test'
bar['123.com'] = function() print(bar.name) end
bar['123.com']()

function bar:addBar(name)
    bar[name] = function() print(self.name) end
end

bar:addBar('456.com')

bar['456.com']()
于 2012-04-18T04:21:27.697 回答
1

天啊...

bar = {
    ['123.com'] = function(self)
        print("YAY!", self)
    end
}
function f()
    print(bar)
    bar:WHATTHE()
end

function crazy(f, patt, repl)
    local f_str = string.dump(f)
    local newf_str = string.gsub(f_str, "WHATTHE", "123.com")
    assert(#newf_str == #f_str, "replacement must be of same length")
    local newf = loadstring(newf_str)
    setfenv(newf, getfenv(f))
    return newf
end

f = crazy(f, "WHATTHE", "123.com")

f()
--[[ Output:
    table: 005EB688
    YAY!    table: 005EB688
]]

永远不要这样做。

于 2012-04-18T09:50:24.777 回答