您好我有以下一些代码似乎可行,但我不知道为什么 - 我已经构建了一个如下的测试类
class testclass {
int ivalue;
public:
int getivalue();
void setivalue(int &v);
};
然后注册了testclass(为实际功能留出的位,但它们非常基本)。这是我不遵循的元表的注册。 (etivalue和setivalue是调用同名类函数的c函数)
static const struct luaL_Reg arraylib_f [] = {
{"new", new_testclass},
{NULL, NULL}
};
static const struct luaL_Reg arraylib_m [] = {
{"set", setivalue},
{"get", getivalue},
{NULL, NULL}
};
int luaopen_testclass (lua_State *L) {
luaL_newmetatable(L, "LuaBook.testclass");
lua_pushvalue(L, -1); /* duplicates the metatable */
lua_setfield(L, -2, "__index");
luaL_register(L, NULL, arraylib_m);
luaL_register(L, "testclass", arraylib_f);
return 1;
}
我不明白的是我正在将函数添加到metatable的__index中 我跑的时候
a = testclass.new()
a:set(10)
print(a:get())
然后按预期工作。我不明白的是为什么在我认为我已经将它加载到__index metatable时调用该集合?那是我做过的还是别的什么?
TIA
答案 0 :(得分:4)
int luaopen_testclass (lua_State *L) {
luaL_newmetatable(L, "LuaBook.testclass"); //leaves new metatable on the stack
lua_pushvalue(L, -1); // there are two 'copies' of the metatable on the stack
lua_setfield(L, -2, "__index"); // pop one of those copies and assign it to
// __index field od the 1st metatable
luaL_register(L, NULL, arraylib_m); // register functions in the metatable
luaL_register(L, "testclass", arraylib_f);
return 1;
}
该代码等同于示例Lua代码:
metatable = {}
metatable.__index = metatable
metatable.set = function() --[[ stuff --]] end
metatable.get = function() --[[ stuff --]] end
我假设'new_testclass'C函数为返回的表设置元表“LuaBook.testclass”。
在您的代码中,您不会向metatable __index字段添加函数。将指向metatable的指针分配给名为__index的metatable的字段,并向其注册set和get函数。
现在,如果你将metatable设置为'new_testclass'函数返回的值(我假设你这样做) - 让我们调用那个值'foo',你调用foo:set(10),而不是Lua:
我希望这可以帮助你弄清楚这里发生了什么。
答案 1 :(得分:1)
如果我理解了您的问题,那么您就会问set()
get()
如何通过__index
元方法调用。
代码可以用纯lua表示:
local o = {}
function o.get(self)
return self.ivalue
end
function o.set(self, val)
self.ivalue = val
end
a = {}
mt = {
__index = function(t, n)
return o[n]
end
}
setmetatable(a, mt)
print(a:get())
a:set(10)
print(a:get())
结果:
nil
10
在此示例中,mt
表被设置为a
表的metatable。 __index
和get
同时调用set
元方法,因为表get
中当前不存在set
或a
。
如果更改此示例而不是:
local o = {}
function o.get(self)
return self.ivalue
end
function o.set(self, val)
self.ivalue = val
end
a = {}
function a.get(self)
print('here')
return self.ivalue
end
mt = {
__index = function(t, n)
return o[n]
end
}
setmetatable(a, mt)
print(a:get())
a:set(10)
print(a:get())
结果:
here
nil
here
10
在这种情况下,__index
元方法为get()
调用 NOT ,因为get
表中已存在a
索引。
一旦您了解了它们的工作原理,就可以使用元方法创建许多有趣的构造。我建议阅读13.4.1 - The __index Metamethod in PiL并再做一些例子。以上所有内容也可以从 c api 完成。