我不太了解堆栈。
lua_gettop()
返回栈顶元素的索引。因为索引从 1 开始,所以这个结果等于堆栈中元素的数量(因此 0 意味着一个空堆栈)。
那么它和-1有什么区别?
lua_getglobal(L,"Foo");
if( lua_isfunction(L,lua_gettop(L)) ) {
lua_getglobal(L,"Foo");
if( lua_isfunction(L,-1) ) {
您可以将堆栈想象为从底部开始增长,底部(即第一个推送)元素的索引为 1,然后您推送另一个元素(索引 2),然后是另一个(索引 3),等等。所以你有这个情况:
+-----------------------+
| element with index 6 | <-- top ("relative" index -1)
+-----------------------+
| element with index 5 | <-- -2
+-----------------------+
| element with index 4 | <-- -3
+-----------------------+
| element with index 3 | <-- -4
+-----------------------+
| element with index 2 | <-- -5
+-----------------------+
| element with index 1 | <-- bottom ("relative" index -6 )
+-----------------------+
您也可以说“正常索引”(从底部开始的索引)是元素的绝对索引(类似于 C 中的数组,除了从 1 开始)。相反,负索引与堆栈顶部“相对”。lua_gettop
为您提供堆栈顶部的绝对索引(始终具有相对索引-1
)。
那么,为什么有两种索引堆栈的方法呢?因为有时访问数组之类的元素(使用绝对索引)很有用,有时您只需要访问最后推送的元素(因此从顶部开始索引)。
顺便说一句,我通常想象 Lua 堆栈反转:从上面开始并向下增长(即堆栈顶部位于我心理表征的底部)。我发现这个心智模型更有用,因为我将索引 -1 解释为“在代码中后退(因此向上),直到你找到第一个推动”。以这种方式,索引 -2 将是“在代码中后退一步,直到找到第二次推送”等等。所有这些都有助于我快速确定我推送了什么。
但是,为了避免混淆,这里我使用了更经典的表示,堆栈顶部实际上是在顶部绘制的!
来自 PIL ( http://www.lua.org/pil/24.2.3.html )
请注意,负索引 -x 等价于正索引 gettop - x + 1。
所以
if( lua_isfunction(L,lua_gettop(L)) ) {
做的比
if( lua_isfunction(L,-1) ) {
如果您立即将其用作这样的索引,则没有区别。但是你可以用它做其他事情,比如存储索引并在以后使用它,当它可能不再是最后一个索引时。
正如您已经说过的, lua_gettop 返回堆栈顶部元素的索引。如果堆栈为空,则索引 -1 上没有元素。因此,函数 lua_gettop 为您提供了可以使用的索引的边界。