3

一个初学者关于 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));了,它以错误告终。

回答

正如Nneonneo 所注意到的,这是使用中的 Lua 版本的问题。上述工作似乎需要 Lua 5.2。

4

1 回答 1

6

来自http://lua-users.org/wiki/LuaFaq

为什么 __gc 和 __len 元方法不适用于表?

__lenon tables 计划在 5.2 中得到支持。请参阅 LuaFiveTwo。

由于您使用的是 5.1,__len因此在表上不起作用。事实上,在 Lua 5.2 上运行你的代码会产生

1
1

正如预期的那样。

于 2012-10-07T06:08:38.900 回答