这是一个潜在的模式,可以检查参数是否是一个表:
int my_fn(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
// .. do stuff with the table ..
}
只要第一个参数是表,这就有效。但是,其他Lua类型支持表查找,例如userdata,在luajit中支持cdata。
在我调用之前,是否有一种很好的方法可以检查表查找(例如via lua_getfield
)是否会成功?我的意思是不限制表格的类型。相关地,table,userdata和cdata是luajit中唯一支持索引查找的类型吗?
我最感兴趣的是限于Lua 5.1 C API的答案,因为我使用的LuaJIT目前适用于此版本。
澄清
luaL_checkXXX
函数的优点在于,在一行中,它们是:
我正在为桌子寻找类似的东西。我不希望C友好的哈希表返回值,但如果有问题的参数不可索引,我做希望向用户提供相同质量的错误消息。
我接受了鸭子打字的哲学。如果我编写一个只想从参数中索引某些键的函数,那么我就不在乎该参数是真正的表,还是只关注支持__index
查找的用户数据。我想接受其中任何一个。
答案 0 :(得分:0)
通常,只有表具有查找,因为它是唯一定义此属性的类型。 Userdata是不透明的,只是主机知道如何处理它或者为特定行为添加metatable(可以分析)。 CData是Lua用LuaJIT编译的一部分,我从未在C API中使用过这种类型(它是否支持?)。最后,您必须检查类型/元表以查找可能的查找并请求字段检查设置,lua_getfield
无法解决(但原始访问应该更快,请参阅lua_rawget
)。例外情况是按lua_objlen
检查表数组长度。
此外,更便宜的类型检查解决方案是lua_is***
函数。
答案 1 :(得分:0)
这是一种方法:
// If the value at index narg is not indexable, this function does not return and
// provides a user-friendly error message; otherwise the stack is unchanged.
static void luaL_checkindexable(lua_State *L, int narg) {
if (lua_istable(L, narg)) return; // tables are indexable.
if (!luaL_getmetafield(L, narg, "__index")) {
// This function will show the user narg and the Lua-visible function name.
luaL_argerror(L, narg, "expected an indexable value such as a table");
}
lua_pop(L, 1); // Pop the value of getmetable(narg).__index.
}
这适用于表及其元表上具有__index
值的任何值。
它提供luaL_argerror
给出的标准格式错误。这是一个示例错误消息:
a_file.lua:7: bad argument #1 to 'fn' (expected an indexable value such as a table)
你可以像这样使用它:
// This Lua-facing function expects an indexable 1st argument.
int my_fn(lua_State *L) {
luaL_checkindexable(L, 1);
lua_getfield(L, 1, "key"); // --> arg1.key or nil is now on top of stack.
// .. your fn ..
}