Lua 如何检测userdata是否有;环境表;?

Lua 如何检测userdata是否有;环境表;?,lua,Lua,在Lua5.1中,可以将环境表与userdata关联。这让我们可以将“字段”添加到各个用户数据中 显而易见的方法是在创建userdata时创建这个环境表,可能是一个空表。然而,在我的应用程序中,会有许多用户数据不一定需要这个环境表,它们很快就会消失。我不想因为创建这么多临时空表而产生不可用的开销 因此,相反,我认为只有在检测到userdata没有我创建的环境表时,才创建环境表 问题在于,在Lua5.1中,默认的环境表不是nil。它应该是全局表,\u G(我想知道这到底有多有用)。因此,假设我会通

在Lua5.1中,可以将环境表与userdata关联。这让我们可以将“字段”添加到各个用户数据中

显而易见的方法是在创建userdata时创建这个环境表,可能是一个空表。然而,在我的应用程序中,会有许多用户数据不一定需要这个环境表,它们很快就会消失。我不想因为创建这么多临时空表而产生不可用的开销

因此,相反,我认为只有在检测到userdata没有我创建的环境表时,才创建环境表

问题在于,在Lua5.1中,默认的环境表不是
nil
。它应该是全局表,
\u G
(我想知道这到底有多有用)。因此,假设我会通过执行以下操作来测试未初始化的userdata:

/*“index”是我的用户数据所在的位置*/
lua_getfenv(L,指数);
初始化=lua_rawequal(L,索引,lua_GLOBALSINDEX);
现在,我的问题是:


我需要使用LUA_ENVIRONINDEX还是LUA_GLOBALSINDEX?还是我需要做点别的?此测试在绝对任何场景中都有效吗?

通常您会遇到全局表
\u G
表作为用户数据的默认环境,具体取决于调用
lua\u newuserdata的C函数的函数环境(请参阅)。通过
require
加载的扩展模块中的Userdata通常将
package
表作为默认环境,因为
require
将该表设置为环境,并由所有注册的C函数和在其中创建的Userdata继承<另一方面,code>newproxy
\u G
设置为默认环境

原则上,如果有人更改C函数的函数环境,您可以将任何表作为默认环境(这是非常罕见的)。实际上,检查
\u G
表就足够了。为此,您需要用户数据的环境表、包和全局表的有效索引:

lua_getfenv( L, index ); /* pushes the environment of the ud to stack */
lua_getglobal( L, "package" ); /* pushes the package table to stack */
/* the globals table is always available at LUA_GLOBALSINDEX, so no need to push
 * anything ... */
hasdefaultenv = lua_rawequal( L, -2, -1 ) /* compare env to package table */
             || lua_rawequal( L, -2, LUA_GLOBALSINDEX ); /* compare env to _G */
您可能希望将
表保存在某个位置(例如,在upvalue中),这样就没有人可以通过替换
表来扰乱您的测试

然而,最可靠的解决方案是在创建用户数据时将一个唯一的共享虚拟表设置为环境(您可以使用
\u G
),并在必要时检查和替换该虚拟表


顺便说一句,
LUA_ENVIRONINDEX
用于获取的环境,而不是用于获取用户数据的环境。

回答得非常好。建议显式地将环境设置为
\u G
,这是一个非常好的建议。