2

这是一个可以检查参数是否为表的潜在模式:

int my_fn(lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  // .. do stuff with the table ..
}

每当第一个参数是表格时,这都有效。但是,其他 Lua 类型支持表查找,例如 userdata,在 luajit 中支持 cdata。

lua_getfield有没有一种很好的方法可以在我调用它之前检查表查找(例如 via )是否会成功?我的意思是不将类型限制为表格。相关地,表、userdata 和 cdata 是 luajit 中唯一支持索引查找的类型吗?

我对仅限于 Lua 5.1 C API 的答案最感兴趣,因为我正在使用目前适用于此版本的 LuaJIT。

澄清

这些函数的优点luaL_checkXXX是,在一行中,它们:

  • 如果类型错误,则抛出信息丰富、用户友好的错误消息,并且
  • 提供可立即使用的 C 友好返回值。

我正在为桌子寻找类似的东西。我不期望 C 友好的哈希表返回值,但如果有问题的参数不可索引,我确实希望向用户提供相同质量的错误消息。

我接受鸭子打字的哲学。如果我编写的函数只是想从参数中索引一些键,那么我不在乎该参数是否真的是一个表,或者只是一个支持__index查找的用户数据。我想接受任何一个。

4

2 回答 2

0

通常,只有表具有查找功能,因为它是唯一定义此属性的类型。用户数据是不透明的,只有主机知道如何处理它或为特定行为添加一个元表(可以分析)。CData 是使用 LuaJIT 编译的 Lua 的一部分,我从未将这种类型与 C API 一起使用(甚至支持吗?)。最后,您必须检查类型/元表以进行可能的查找并请求一个字段来检查设置,这是没有办法的lua_getfield(但原始访问应该更快,请参阅lua_rawget)。例外情况是通过 . 检查表数组长度lua_objlen

此外,更便宜的类型检查解决方案是lua_is***函数。

于 2015-09-26T01:14:54.067 回答
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 ..
}
于 2015-09-29T19:02:37.573 回答