您始终可以在元表中存储一个标记字段,其中包含模块独有的轻量用户数据值。
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 中检索和调用这些函数。