[英]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.