从元表字段/方法访问数组索引。

我有一些元表,反映了一些 C++ 类/结构体。通常我依靠 __index 来调用任何对象的字段/方法并在一个函数中解决它们。

我的困难是当我想要将参数传递给字段时,就像这样:

anim = playerInfo.animations
while anim do

  print (anim)

  numstates = anim.numstates
  for i = 1, numstates do

    state = anim.states(i)  <--- 这一行就是问题所在
    print(state)

  end

  anim = anim.next

end

这是相关的 C 代码:

static const struct luaL_Reg objanimationlib_m[] = {
    {"__tostring", objanimation2string},
    {"__index", objanimationget},
    {"__newindex", objanimationset},
    {NULL, NULL}
};

    luaL_newmetatable(L, "objanimation");
    lua_pushvalue(L, -1); // 重复元表
    luaL_setfuncs(L, objanimationlib_m, 0);

在 __index 函数内部:

else if (!strcmp(field, "states"))
{
    int number = (int)luaL_checknumber(L, 3) - 1; // -1 因为 Lua 不是基于 0 的
    if (number >= anim->numstates)
        return 0;

    PushUserdata(&anim->states[number], "objstate");
}

运行脚本,我收到了一个错误:

Warning: [string "test.lua"]:13: bad argument #3 to '__index' (number expected, got no value)

我觉得我错过了一些愚蠢的简单东西。是什么呢?

编辑:这是我的解决方案,在 __index 函数内部:

else if (!strcmp(field, "states"))
{
    lua_newtable(L);

    int i;
    for (i = 0; i < anim->numstates; i++)
    {
          PushUserdata(&anim->states[i], "objstate");
          lua_rawseti(L, -2, i+1);
    }
}

这将返回一个充满 userdata 元素的表。可能很昂贵,因此这也会增加性能:

anim = playerInfo.animations
while anim do

  print (anim)

  numstates = anim.numstates
  states = anim.states
  for i = 1, numstates do

    print(states[i])

  end

  anim = anim.next

end
点赞
用户107090
用户107090

state = anim.states(i) 等同于 do local f=anim.states; state=f(i) end, 所以你的元方法永远不会看到 i

换句话说,索引元方法接收两个参数,即表和键。它返回的内容不一定受到任何元方法的影响,除非你显式地这样做。

我会定义 __len 返回 numstates 并定义 __call 处理 anim.states(i),这样你的代码就可以这样写:

  for i = 1, #anim do
    state = anim(i)
    print(state)
  end
2014-06-16 17:25:43