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


27.3.1 – 注册表

注册表始终位于一个伪索引中,其值由 LUA_REGISTRYINDEX 定义。伪索引类似于栈中的索引,不同之处在于其关联值不在栈中。Lua API 中大多数接受索引作为参数的函数也接受伪索引——例外情况是那些操纵栈本身的函数,例如 lua_removelua_insert。例如,要获取注册表中使用键 "Key" 存储的值,可以使用以下代码

    lua_pushstring(L, "Key");
    lua_gettable(L, LUA_REGISTRYINDEX);

注册表是一个常规的 Lua 表。因此,您可以使用任何 Lua 值(但不能使用 nil)对其进行索引。但是,由于所有 C 库共享同一个注册表,因此您必须谨慎选择用作键的值,以避免冲突。一种万无一失的方法是将代码中静态变量的地址用作键:C 链接编辑器确保此键在所有库中都是唯一的。要使用此选项,您需要函数 lua_pushlightuserdata,它将表示 C 指针的值压入 Lua 栈中。以下代码展示了如何使用此方法在注册表中存储和检索数字

    /* variable with an unique address */
    static const char Key = 'k';
    
    /* store a number */
    lua_pushlightuserdata(L, (void *)&Key);  /* push address */
    lua_pushnumber(L, myNumber);  /* push value */
    /* registry[&Key] = myNumber */
    lua_settable(L, LUA_REGISTRYINDEX);
    
    /* retrieve a number */
    lua_pushlightuserdata(L, (void *)&Key);  /* push address */
    lua_gettable(L, LUA_REGISTRYINDEX);  /* retrieve value */
    myNumber = lua_tonumber(L, -1);  /* convert to number */
我们将在第 28.5 节中更详细地讨论轻量级用户数据。

当然,您也可以使用字符串作为注册表的键,只要您选择唯一名称即可。当您希望允许其他独立库访问您的数据时,字符串键特别有用,因为它们只需要知道键名即可。对于此类键,没有选择名称的万无一失的方法,但有一些好的做法,例如避免使用通用名称并使用库名称或类似名称作为前缀。lualualib 等前缀不是好的选择。另一种选择是使用通用唯一标识符 (uuid),因为现在大多数系统都有生成此类标识符的程序(例如,Linux 中的 uuidgen)。uuid 是一个 128 位数字(以十六进制形式写入以形成字符串),它由主机 IP 地址、时间戳和随机组件组合生成,因此它肯定不同于任何其他 uuid