【发布时间】:2016-10-12 04:20:43
【问题描述】:
为什么这段代码会失败(尝试调用方法'sort'(一个nil值))
th> xyz = {1,2,3}
th> xyz:sort()
虽然有效
th> table.sort(xyz)
【问题讨论】:
为什么这段代码会失败(尝试调用方法'sort'(一个nil值))
th> xyz = {1,2,3}
th> xyz:sort()
虽然有效
th> table.sort(xyz)
【问题讨论】:
因为table 表包含标准库提供的用于操作表的通用函数,默认情况下不在表的元表中。实际上,除非明确指定,否则表没有元表。
您可以手动执行此操作:
local xyz = {1,2,3}
local mt = { __index = table}
setmetatable(xyz, mt)
xyz:insert(2)
xyz:sort()
【讨论】:
print(xyz:unpack()) 表方法的另一个很好的用法。
@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 explains,您的表没有“排序”字段或元表,因此索引结果为nil,导致尝试调用零值时出错。 (该消息很好地表明您使用了冒号语法,称它是“方法调用”。)
【讨论】:
这是因为xyz 没有键/值对,其中键为"sort",值是函数。 table 表示键/值对。试试这个让事情更清楚:
local xyz = {}
print(xyz.sort) -- prints nil
print(table.sort) -- prints function: 0xabcd1234
【讨论】: