你好 metatable.__len 世界

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参考手册—元表和元方法# 等同于以下内容:

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));,结果出现错误。

回答

正如_Nneonneo_注意到的那样,这是使用的 Lua 版本的问题。似乎需要 Lua 5.2 才能使上述代码工作。

点赞
用户1204143
用户1204143

为什么在表上不起作用 __gc 和 __len 元方法?

在表中使用 __len 该方法计划在5.2中支持。请参考 LuaFiveTwo。

由于您正在使用5.1版本,因此在表上使用 __len 是无效的。实际上,在 Lua 5.2 上运行您的代码将产生如下结果:

1
1

如预期一样。

2012-10-07 06:08:38