关于 Lua 中的冒号操作符

为什么这段代码会出错(尝试调用一个空值的方法 'sort')

th> xyz = {1,2,3}
th> xyz:sort()

而这段代码却可以正常工作

th> table.sort(xyz)
点赞
用户1009479
用户1009479

因为 table 表格,其中包含标准库提供的用于操作表格的通用函数,不会默认成为表格的元表。实际上,除非明确指定,否则表格没有元表。

您可以手动实现这个:

local xyz = {1,2,3}
local mt = { __index = table}
setmetatable(xyz, mt)
xyz:insert(2)
xyz:sort()
2016-06-11 08:07:19
用户2226988
用户2226988

@YuHao 给出了直接的答案。这里提供一些更多的背景信息。

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

表达式:标识符(arg0, arg1, ...)

在概念上等同于

local lhs = 表达式
lhs.identifer(lhs, arg0, arg1, ...)

在概念上等同于

local lhs = 表达式
lhs["identifer"](lhs, arg0, arg1, ...)

所以,你的问题本质上不是关于冒号操作符,而是关于索引。

在 Lua 中,对一个表类型的值进行索引首先检查表的字段来找到键的值。如果找到,返回该值。

如果没有找到,则检查该表的一个可选元表,如果该表有一个键值为 "__index" 的元素。如果找不到,则索引结果为 nil。如果 __index 字段的值为一个表,则在该表上重复此过程。如果该值为一个函数,则索引结果为调用该函数的返回值。

在你的例子中,正如 @YuHao 解释的那样,你的表没有 "sort" 字段,也没有元表。因此,索引结果为 nil,导致你尝试调用空值的错误。(该消息很好地表明了你使用了冒号语法,称其为 "方法调用"。)

2016-06-11 15:47:02
用户88888888
用户88888888

这是因为 xyz 没有一个键值对,其中键是 "sort",值是一个函数。table 有上述的键值对。试试以下代码更清晰地说明问题:

local xyz = {}
print(xyz.sort)    -- 打印 nil
print(table.sort)  -- 打印 function: 0xabcd1234
2016-08-11 01:04:33