初学者关于Lua和 metatables 的问题,其中一个简单的例子是Hello-World,涉及len
事件,遗憾的是它不会返回预期的结果(我是使用从Ubuntu官方存储库安装的Lua 5.1。
以下是示例:
Test_Type = {};
function Test_Type.__len (o)
return 1;
end;
function new_test ()
local result = {};
setmetatable(result, Test_Type);
return result;
end;
do
local a_test = new_test();
print (#a_test);
print(getmetatable(a_test).__len(a_test));
end;
结果我得到了:
0
1
我期待第一个打印语句显示1
,但显示0
,令我大吃一惊。
我错过了什么?
根据Lua Reference Manual — Metatables and Metamethods,#
等同于此:
function len_event (op)
if type(op) == "string" then
return strlen(op) -- primitive string length
else
local h = metatable(op).__len
if h then
return (h(op)) -- call handler with the operand
elseif type(op) == "table" then
return #op -- primitive table length
else -- no handler available: error
error(···)
end
end
end
所以print (#a_test);
和print(getmetatable(a_test).__len(a_test));
会产生相同的结果,不是吗?
顺便说一下,为什么参考手册中的上述摘录是metatable(op)
,而getmetatable(op)
应该是print(metatable(a_test).__len(a_test));
?至少我已经尝试了{{1}},结果就是错误。
正如 Nneonneo 注意到的,这是使用中的Lua版本的问题。 Lua 5.2似乎是上述工作所必需的。
答案 0 :(得分:6)
来自http://lua-users.org/wiki/LuaFaq:
为什么__gc和__len元方法不能用于表格?
表中的
__len
计划在5.2中得到支持。见LuaFiveTwo。
由于您使用的是5.1,表格上的__len
不起作用。实际上,在Lua 5.2上运行代码会产生
1
1
正如所料。