关于Lua中的冒号运算符

3
为什么这段代码会失败(尝试调用方法“sort”(一个空值))?
th> xyz = {1,2,3}                                                                      
th> xyz:sort()

虽然这个可以运行

th> table.sort(xyz)
3个回答

10
因为标准库提供的用于操作表格的通用函数集合所在的 table 表格默认情况下不是任何一个表格的元表。事实上,除非显式指定,否则表格将没有元表。
但是你可以手动添加元表:
local xyz = {1,2,3}
local mt = { __index = table}
setmetatable(xyz, mt)
xyz:insert(2)
xyz:sort()

print(xyz:unpack()) 另一个漂亮的使用表格方法。 - Tom Blodget
2
这与字符串类型的值形成对比,后者(在Lua的最新版本中)最初具有标准字符串表作为__index元方法。 - Tom Blodget

4

@YuHao 给出了直接的答案。以下是更多背景信息。

冒号操作符是一个索引操作符;它使用右侧的标识符(作为字符串类型的键)对左侧表达式的值进行索引。

expression:identifier(arg0, arg1, ...)

在概念上与相同

local lhs = expression
lhs.identifer(lhs, arg0, arg1, ...)

概念上与...相同

local lhs = expression
lhs["identifer"](lhs, arg0, arg1, ...)

所以,你的问题与冒号运算符不太相关,而是关于索引。
在Lua中,对表类型的值进行索引时,首先检查表的字段是否有该键。如果找到,则返回其值。
如果没有找到,则检查该表是否有一个可选的元表,并且如果该表具有键“__index”的值。如果没有找到,则索引的结果为nil。如果__index字段的值是一个表,则该过程在该表上重复。如果该值是一个函数,则索引的结果是调用该函数的返回值。
在你的情况下,正如@YuHao 解释的那样,你的表没有“sort”字段也没有元表,因此索引结果为nil,导致尝试调用空值的错误。(消息很好地指出了你使用了冒号语法,称其为“方法调用”)。

0
这是因为xyz没有一个键/值对,其中键是"sort",值是一个函数。table有这样的键/值对。尝试这个来使事情更清晰:
local xyz = {}
print(xyz.sort)    -- prints nil
print(table.sort)  -- prints function: 0xabcd1234

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接