您始终可以在元表中存储一个标记字段,其中包含您的模块特有的轻用户数据值。
static const char *green_flavor = "green";
...
void my_setflavor(lua_State *L, void *flavor) {
lua_pushlightuserdata(L,flavor);
lua_pushlstring(L,"_flavor");
lua_rawset(L,-3);
}
void my_isflavor(lua_State *L, void *flavor) {
void *p = NULL;
lua_pushlstring(L,"_flavor");
lua_rawget(L,-2);
p = lua_touserdata(L,-1);
lua_pop(L,1);
return p == flavor;
}
然后你可以使用my_setflavor(L,&green_flavor)
将表的 _flavor 字段设置在堆栈顶部,并且my_isflavor(L,&red_flavor)
测试堆栈顶部表的 _flavor 字段。
以这种方式使用,_flavor 字段只能采用可由范围内具有符号 green_flavor 的模块中的代码创建的值,并且除了检索元表本身之外,查找该字段并测试其值只需要一次表查找。请注意,变量 green_flavor 的值并不重要,因为实际仅使用其地址。
由于有多个不同的风味变量可用作标记值,因此 _flavor 字段可用于区分多个相关的元表。
综上所述,一个自然的问题是“为什么要这样做?”毕竟,元表可以轻松包含获得适当行为所需的所有信息。它可以轻松保存函数和数据,并且可以从 C 和 Lua 检索和调用这些函数。