第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但存在一些差异。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买这本书,您还可以帮助支持 Lua 项目


24.2.2 – 查询元素

为了引用堆栈中的元素,API 使用索引。堆栈中的第一个元素(即首先压入的元素)的索引为 1,下一个元素的索引为 2,依此类推。我们还可以使用堆栈顶部作为参考,使用负索引来访问元素。在这种情况下,-1 引用顶部元素(即最后压入的元素),-2 引用前一个元素,依此类推。例如,调用 lua_tostring(L, -1) 将堆栈顶部的值作为字符串返回。正如我们将看到的,在很多情况下,从底部(即使用正索引)索引堆栈是自然的,而在其他情况下,使用负索引是自然的。

为了检查元素是否具有特定类型,API 提供了一系列函数 lua_is*,其中 * 可以是任何 Lua 类型。因此,有 lua_isnumberlua_isstringlua_istable 等。所有这些函数都有相同的原型

    int lua_is... (lua_State *L, int index);
lua_isnumberlua_isstring 函数不检查值是否具有该特定类型,而是检查值是否可以转换为该类型。例如,任何数字都满足 lua_isstring

还有一个函数 lua_type,它返回堆栈中元素的类型。(某些 lua_is* 函数实际上是使用此函数的宏。)每种类型都由头文件 lua.h 中定义的常量表示:LUA_TNILLUA_TBOOLEANLUA_TNUMBERLUA_TSTRINGLUA_TTABLELUA_TFUNCTIONLUA_TUSERDATALUA_TTHREAD。此函数主要与 switch 语句结合使用。当我们需要在不进行强制转换的情况下检查字符串和数字时,它也很有用。

要从堆栈中获取值,可以使用 lua_to* 函数

    int            lua_toboolean (lua_State *L, int index);
    double         lua_tonumber (lua_State *L, int index);
    const char    *lua_tostring (lua_State *L, int index);
    size_t         lua_strlen (lua_State *L, int index);
即使给定的元素没有正确的类型,也可以调用它们。在这种情况下,lua_tobooleanlua_tonumberlua_strlen 返回零,而其他函数返回 NULL。零没有用,但 ANSI C 没有提供我们可用来指示错误的无效数字值。但是,对于其他函数,我们经常不需要使用相应的 lua_is* 函数:我们只需调用 lua_to*,然后测试结果是否不为 NULL

lua_tostring 函数返回一个指向字符串内部副本的指针。你无法更改它(那里有一个 const 来提醒你)。Lua 确保只要相应的值在堆栈中,此指针就是有效的。当 C 函数返回时,Lua 会清除其堆栈;因此,作为一项规则,你永远不应该将指向 Lua 字符串的指针存储在获取它们的函数之外。

lua_tostring 返回的任何字符串在其末尾始终都有一个零,但它可以在其内部有其他零。lua_strlen 函数返回字符串的正确长度。特别是,假设堆栈顶部的值是一个字符串,则以下断言始终有效

    const char *s = lua_tostring(L, -1);   /* any Lua string */
    size_t l = lua_strlen(L, -1);          /* its length */
    assert(s[l] == '\0');
    assert(strlen(s) <= l);