2

我想知道如何从http://lua-users.org/wiki/MetamethodsTutorial编写类似 Lua Snippet 的内容

local func_example = setmetatable({}, {__index = function (t, k)
  return "key doesn't exist"
end})

local fallback_tbl = setmetatable({
  foo = "bar",
  [123] = 456,
}, {__index=func_example})

local fallback_example = setmetatable({}, {__index=fallback_tbl})

print(func_example[1]) --> key doesn't exist
print(fallback_example.foo) --> bar
print(fallback_example[123]) --> 456
print(fallback_example[456]) --> key doesn't exist

在 lua C api 中。即我希望 lua 首先检查一个键是否在成员元表中,否则调用 __index 实现。我想出了这样的事情:

static const struct luaL_reg
lobj_fallback[] = {
    {"__index", lobject_index},
    {"__newindex", lobject_newindex},
    {"__tostring", lobject_tostring},
    {NULL, NULL}, 
};

static const struct luaL_reg
lobj_members[] = {
    {"delete", lobject_delete},
    {NULL, NULL}
};

{
    // ....
    luaL_newmetatable(L,  "MyMetaTable");
    luaL_register(L, NULL, lobj_members);

    luaL_newmetatable(L, "MyMetaTableFallback");
    luaL_register(L, NULL, lobj_fallback);

    lua_setmetatable(L, -2);
    // ...
}

然而这并没有按预期工作,处理后备 __index 工作但不是成员元表(“尝试调用方法'删除'(一个零值)”)。

4

1 回答 1

4

如果您打算在访问“MyMetaTable”时回退到索引功能,那么您已经交换了表和元表的名称。因此,成员表 (lobj_members) 被称为“MyMetaTableFallback”,而元表 (lobj_fallback) 被称为“MyMetaTable”。

于 2013-09-23T12:06:23.887 回答