第一版是針對 Lua 5.0 編寫的。雖然在後續版本中仍然有很大的相關性,但有一些差異。
第四版針對 Lua 5.3,可以在 Amazon 和其他書店買到。
購買這本書,也可以 贊助 Lua 專案


24.2.3 – 其他堆疊操作

除了上述在 C 和堆疊之間交換值的函式,API 也提供下列用於一般堆疊操作的函式

    int   lua_gettop (lua_State *L);
    void  lua_settop (lua_State *L, int index);
    void  lua_pushvalue (lua_State *L, int index);
    void  lua_remove (lua_State *L, int index);
    void  lua_insert (lua_State *L, int index);
    void  lua_replace (lua_State *L, int index);
lua_gettop 函式會傳回堆疊中的元素數量,這也是最上層元素的索引。請注意,負索引 -x 等於正索引 gettop - x + 1

lua_settop 會將最上層(也就是堆疊中的元素數量)設定為特定值。如果先前的最上層高於新的最上層,最上層的值會被捨棄。否則,函式會在堆疊中加入 nil,以取得指定的長度。特別情況下,lua_settop(L, 0) 會清空堆疊。您也可以在 lua_settop 中使用負索引;這會將最上層元素設定為指定的索引。使用此功能,API 提供下列巨集,可以從堆疊中彈出 n 個元素

    #define lua_pop(L,n)  lua_settop(L, -(n)-1)

lua_pushvalue 函式會在堆疊的最上層加入指定索引處元素的副本;lua_remove 會移除指定索引處的元素,將該位置上方所有元素向下移動以填補空缺;lua_insert 會將最上層元素移到指定位置,將該位置上方所有元素向上移動以騰出空間;最後,lua_replace 會從最上層彈出一個值,並將其設定為指定索引處的值,而不會移動任何東西。請注意,下列操作不會對堆疊造成影響

    lua_settop(L, -1);  /* set top to its current value */
    lua_insert(L, -1);  /* move top element to the top */

為了說明這些函式的用法,以下是一個有用的輔助函式,可以傾印堆疊中的所有內容

    static void stackDump (lua_State *L) {
      int i;
      int top = lua_gettop(L);
      for (i = 1; i <= top; i++) {  /* repeat for each level */
        int t = lua_type(L, i);
        switch (t) {
    
          case LUA_TSTRING:  /* strings */
            printf("`%s'", lua_tostring(L, i));
            break;
    
          case LUA_TBOOLEAN:  /* booleans */
            printf(lua_toboolean(L, i) ? "true" : "false");
            break;
    
          case LUA_TNUMBER:  /* numbers */
            printf("%g", lua_tonumber(L, i));
            break;
    
          default:  /* other values */
            printf("%s", lua_typename(L, t));
            break;
    
        }
        printf("  ");  /* put a separator */
      }
      printf("\n");  /* end the listing */
    }
此函式從底部到頂部遍歷堆疊,根據每個元素的類型印出它。它使用引號印出字串;對於數字,它使用 `%g´ 格式;對於其他值(表格、函式等),它只印出它們的類型(lua_typename 將類型代碼轉換為類型名稱)。

下列程式使用 stackDump 進一步說明 API 堆疊的處理方式

    #include <stdio.h>
    #include <lua.h>
    
    static void stackDump (lua_State *L) {
      ...
    }
    
    int main (void) {
      lua_State *L = lua_open();
      lua_pushboolean(L, 1); lua_pushnumber(L, 10);
      lua_pushnil(L); lua_pushstring(L, "hello");
      stackDump(L);
                       /* true  10  nil  `hello'  */
    
      lua_pushvalue(L, -4); stackDump(L);
                       /* true  10  nil  `hello'  true  */
    
      lua_replace(L, 3); stackDump(L);
                       /* true  10  true  `hello'  */
    
      lua_settop(L, 6); stackDump(L);
                       /* true  10  true  `hello'  nil  nil  */
    
      lua_remove(L, -3); stackDump(L);
                       /* true  10  true  nil  nil  */
    
      lua_settop(L, -5); stackDump(L);
                       /* true  */
    
      lua_close(L);
      return 0;
    }