[英]When writing a Lua-facing function in C, what's a good way to check if an argument supports table-like lookups?
这是一种可能的模式,可以检查参数是否为表:
int my_fn(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
// .. do stuff with the table ..
}
只要第一个参数是表,此方法就起作用。 但是,其他Lua类型也支持表查找,例如userdata和luajit中的cdata。
有没有一种很好的方法来检查表查找(例如通过lua_getfield
)是否会在我调用它之前成功? 我的意思是不将类型限制为表格。 相关地,表,用户数据和cdata是luajit中唯一支持索引查找的类型吗?
我对仅限于Lua 5.1 C API的答案最感兴趣,因为我使用的是当前与此版本兼容的LuaJIT。
澄清
luaL_checkXXX
函数的优势在于,它们可以在一行中:
我正在寻找类似的表。 我不期望C友好的哈希表返回值,但是如果有问题的参数不可索引,我确实希望向用户提供相同质量的错误消息。
我正在接受鸭子打字的哲学。 如果我编写的函数只是想对某个参数中的某些键编制索引,那么我不在乎该参数是否真正是一个表,或者仅仅是支持__index
查找的userdata。 我要接受任何一个。
通常,只有表才具有查找功能,因为它是定义此属性的唯一类型。 用户数据是不透明的,只有主机知道如何处理或为特定行为添加一个元表(可以分析)。 CData是使用LuaJIT编译的Lua的一部分,我从来没有将此类型与C API一起使用(甚至支持它吗?)。 最后,您必须检查类型/可匹配类型以进行可能的查找,并请求一个字段来检查设置,但是lua_getfield
周围没有办法(但是原始访问应该更快,请参见lua_rawget
)。 例外是通过lua_objlen
检查表数组的长度。
此外,更便宜的类型检查解决方案是lua_is***
函数。
这是一种实现方法:
// 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
上具有__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 ..
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.