Lua中语法糖(冒号)的奇怪行为

时间:2015-11-29 21:55:18

标签: function lua lua-table syntactic-sugar

function string.test(s)
    print('test')
end

a = 'bar'
string.test(a)
a:test()

直到下一个例子,一切都很好。

function table.test(s)
    print('test')
end

b = {1,2,3}
table.test(b)
b:test() -- error

为什么我收到错误?
它在字符串上运行良好。

2 个答案:

答案 0 :(得分:5)

默认情况下,表格没有metatable,就像字符串一样。

尝试改为:

function table.test(s)
    print('test')
end

b = setmetatable({1,2,3}, {__index=table})
table.test(b)
b:test() -- error

答案 1 :(得分:1)

虽然daurn很好地回答了你的问题,但允许解释为什么会这样。

在Lua中,所有数据类型都可以具有元表。 (虽然在处理数字,bool等时有很大不同。请参阅debug.setmetatable。)这包括字符串。默认情况下,这被设置为使用__index索引字符串库,这是在使print(s:sub(1,5))(s是字符串)之类的语法糖成为可能时。

这与表格不同。默认情况下,表没有metatable。您必须使用setmetatable手动设置它。

要结束我的回答,请享受此代码段

debug.setmetatable(0,{__index=math})
debug.setmetatable(function()end,{__index=coroutine})
debug.setmetatable(coroutine.create(function()end), {__index=coroutine})
local function Tab(tab)
    return setmetatable(tab,{__index=table})
end

这基本上允许您在数字上使用数学函数

local x = 5.7
print(x:floor())

使用协同函数执行与函数和线程类似的事情:

print:create():resume()

如果你问我,那很漂亮

当然,创建表并在其上使用表函数:

local x = Tab{1,2,3,4}
x:insert(5)
x:remove(1)
print(x:concat(", "))

我觉得很难想象有谁不喜欢那种酷炫的技巧。