你好metatable .__ len world

Hib*_*u57 3 lua metatable

初学者的有关Lua和问题元表,以作为您好,世界作为一个简单的例子,涉及到的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;
Run Code Online (Sandbox Code Playgroud)

结果我得到了:

0
1
Run Code Online (Sandbox Code Playgroud)

我期待第一个打印声明显示1,但它显示0,令我惊讶的是.

我错过了什么?

根据Lua参考手册 - Metatables和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
Run Code Online (Sandbox Code Playgroud)

所以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似乎是上述工作所必需的.

nne*_*neo 6

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

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

__len表格计划在5.2中得到支持.见LuaFiveTwo.

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

1
1
Run Code Online (Sandbox Code Playgroud)

正如所料.

  • 如果您正在寻找支持__len的Lua 5.1实现,请尝试启用LUAJIT_LUA52_COMPAT的LuaJIT 2. (4认同)