Lua 注册表与轻量级用户数据和引用的区别是什么?

使用 Lua C API,您可以在注册表中保存 Lua 值并稍后检索它。有不同的方法可以实现这一点,您可以创建一个变量并使用它的指针作为注册表中的键,因为它始终是唯一的。您会推送指针作为轻量级用户数据。

您还可以使用 LuaL_ref(L, LUA_REGISTRYINDEX) 创建引用。使用其中一个优点是什么?何时使用引用,何时使用指针?

还有,就引用而言,如果 Lua 垃圾回收程序回收 Lua 值,注册表中的值是否将变为 nil?如果 Lua 更新了 Lua 值,注册表中的值也会更改吗?

点赞
用户5675002
用户5675002

Lua注册表就是另一个Lua表,可以通过预定义的“特殊”索引轻松访问。我猜你不需要解释Lua表与轻量级用户数据的区别。

实际上,你如何索引注册表并不重要,只要你可以在C / C ++端存储那个键。为了方便起见,已经存在函数(luaL_ref / luaL_unref),可以为您提供易于存储和移动的整数键。

关于垃圾收集-规则始终相同。只要值存储在未标记为弱表(注册表不是弱表)的表中,该值就不会被清除。必须从注册表中显式删除值。

更改值将遵循常规Lua规则。将新的不可变值分配给某个变量不会更改存储在注册表中的值,即注册表不会跟随某个变量的更新。但是,更改可变值的内容(表等)是可以的,因为注册表和变量将引用相同的值。

2016-10-22 11:02:13
用户1836540
用户1836540

除了之前的答案之外:

Lua lightuserdatauserdata之间的差异

lightuserdata是一个特殊的Lua类型(以及nilbooleannumberstringtablethread等),包含C指针。没有更多了。您不能为lightuserdata分配元表。相反,您可以为userdata类型分配元表。例如,请参见Lua文件操作,其中文件句柄为具有方法的userdataf:read(“ * all”) f是userdata命令等效于f.read(f,“* all”)

使用整数或C指针索引LUA_REGISTRYINDEX

有两种广泛使用注册表的方法。

1.使用luaL_ref创建对Lua值的新引用,并将返回整数值存储在代码中的某个位置。即,要访问Lua值,您需要读取保存引用的C变量,然后使用lua_rawgeti(L,LUA_REGISTRYINDEX,i)索引注册表,其中i是整数值。 lua_rawseti(L,LUA_REGISTRYINDEX,i)也是可能的,但不要尝试使用此方法将其重写为nil值!

2.您可以创建一个静态C变量static int myvar;,然后使用lua_rawgetp(L,LUA_REGISTRYINDEX,&myvar)lua_rawsetp(L,LUA_REGISTRYINDEX,&myvar)来直接操纵存储的Lua值。

不幸的是,我无法比较这两种方法的性能。我认为它们几乎相同。

2016-10-23 00:43:01