为什么这段代码失败(尝试调用方法'sort'(零值))
th> xyz = {1,2,3}
th> xyz:sort()
虽然这有效
th> table.sort(xyz)
答案 0 :(得分:9)
由于table
表包含用于操作标准库提供的表的通用函数,因此默认情况下不在表的metatable中。实际上,除非明确指定,否则表格没有metatable。
您可以手动执行此操作:
local xyz = {1,2,3}
local mt = { __index = table}
setmetatable(xyz, mt)
xyz:insert(2)
xyz:sort()
答案 1 :(得分:4)
@YuHao直接回答。这是更多背景。
冒号运算符是索引运算符;它使用右侧的标识符(作为字符串类型的键)索引左侧表达式的值。
expression:identifier(arg0, arg1, ...)
在概念上与
相同local lhs = expression
lhs.identifer(lhs, arg0, arg1, ...)
在概念上与
相同local lhs = expression
lhs["identifer"](lhs, arg0, arg1, ...)
所以,你的问题不是关于冒号运算符,而是关于索引的问题。
在Lua中,索引表类型的值首先检查表的字段以获取密钥。如果找到,则返回该值。
如果没有,它会检查表中是否有一个可选的当前关联的metatable,以及该表是否具有键" __ index"的值。如果未找到,则索引的结果为nil
。如果__index字段的值是表,则该进程将在该表上重复。如果值是函数,则索引的结果是调用该函数的返回值。
在您的情况下,作为@YuHao explains,您的表格没有"排序"字段也是metatable,因此索引结果为nil
,导致尝试调用nil值时出错。 (该消息很好地表明您使用了冒号语法,称它是"方法调用"。)
答案 2 :(得分:0)
这是因为xyz
没有键/值对,其中键为"sort"
且值为函数。 table
表示键/值对。试着这个让事情变得更清楚:
local xyz = {}
print(xyz.sort) -- prints nil
print(table.sort) -- prints function: 0xabcd1234