C/C++ 中遍历 Lua table 完整版

在 C/C++ 中遍历一个 Lua table用 lua_next 来实现,这个大家都知道。然而,我却看到很多文章在示范 lua_next 时都只是点到为止,或绝口不提如何获取 key 值,或直接定义该 table 的 key 都是非匿名的,从而简单粗暴地使用 lua_tostring 来获取值。

仔细看看,Lua manual 里对 lua_next 的说明中最后有一句很重要的话:
While traversing a table, do not call lua_tolstring directly on a key, unless you know that the key is actually a string. Recall that lua_tolstring changes the value at the given index; this confuses the next call to lua_next.
遍历 table 的过程中不要直接对处于 -2 位置的 key 做 lua_tostring 操作(还记得这个函数说了它会原地修改栈上的值的吧),除非你确信现在这个 key 就是字符串类型,否则下一次执行 lua_next 就等着意外吧。 好吧,来个完整版,其实不就是把 key 拷贝一份到栈上,然后对这份拷贝进行取值么[1]:
#include 
#include 

void traverse_table(lua_State *L, int index)
{
    lua_pushnil(L); 
    // 现在的栈:-1 => nil; index => table
    while (lua_next(L, index))
    {
        // 现在的栈:-1 => value; -2 => key; index => table
        // 拷贝一份 key 到栈顶,然后对它做 lua_tostring 就不会改变原始的 key 值了
        lua_pushvalue(L, -2);
        // 现在的栈:-1 => key; -2 => value; -3 => key; index => table
        const char* key = lua_tostring(L, -1);
        const char* value = lua_tostring(L, -2);

        printf("%s => %s\n", key, value);

        // 弹出 value 和拷贝的 key,留下原始的 key 作为下一次 lua_next 的参数
        lua_pop(L, 2);
        // 现在的栈:-1 => key; index => table
    }
    // 现在的栈:index => table (最后 lua_next 返回 0 的时候它已经把上一次留下的 key 给弹出了)
    // 所以栈已经恢复到进入这个函数时的状态
}

int main()
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    // 假设现在栈上已经有了一个 talbe,内容为 {one=1,[2]='two',three=3},位置在 top

    traverse_table(L, -1);

    return 0;
}
[1] Iterate through Lua Table

文章来源: http://wutiam.net/notes/191

转载于:https://www.cnblogs.com/islet8/archive/2013/04/11/3014812.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值