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

Weird behavior of syntax sugar(colon) in Lua

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

为什么我会收到错误消息?
它在字符串方面工作得很好。

默认情况下,表没有像字符串那样的元表。

试试看:

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

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

虽然 daurn 很好地回答了您的问题,但请允许我解释一下这是为什么。

在Lua中,所有数据类型都可以有元table。 (尽管在处理数字、布尔值等时完全不同。请参阅 debug.setmetatable。)这包括字符串。默认情况下,这被设置为使用 __index 索引字符串库,这是使语法糖像 print(s:sub(1,5))(s 是一个字符串)成为可能的时候。

这与 tables 不同。默认情况下 table 没有元 table。您必须使用 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()

如果你问我的话,我觉得很老套

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

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

我很难想象有人不喜欢这样的酷把戏。