lua知识点整理

1. lua全局环境和局部环境

local cf = loadstring(" local i=0  i=i+1 print(i) ")

--从后面两个输出我们可以看出,生成的函数的环境就是全局_G
print(cf,getfenv(cf),_G)  -- function: 0058AAB0    table: 00582ED8    table: 00582ED
--改变_G的值
_G = {}
cf()  -- 1
--虽然改变了_G的值,但函数的的环境仍然是全局环境table,地址仍然是0058AAB0
print(cf,getfenv(cf),_G)  -- function: 0058AAB0    table: 00582ED8    table: 0058BFF0

-- function: 0058AAB0    table: 00582ED8    table: 00582ED8
-- 1
-- function: 0058AAB0    table: 00582ED8    table: 0058BFF0
-- [Finished in 0.1s]

 

-- -- 用局部变量list模拟_G(用list表的元素_A保存list表自身,为什么这样做??)
-- local list = {_A = "ddddd", _B = "bbbbb", _C = "ccccc",}
-- list._A = list
-- -- print(list)
-- -- print(list._A)      
-- -- print(list._A._A)      -- 类似:_G._G = _G

-- for k, v in pairs(list) do
--     -- print(k, "=", v, type(v))
-- end

-------------------------------------------------------
-- 搜索:局部变量 -> 全局变量 -> 环境
-- 用局部变量 _A 模拟_G(用list表的元素_A保存list表自身,为什么这样做??)
local _A = {_A = "ddddd", _B = "bbbbb", _C = "ccccc",}
_A._A = _A
print(_A)
print(_A._A)      -- 类似:_G._G = _G    
print(_A._A._A)  

for k, v in pairs(_A) do
    print(k, "=", v, type(v))
end

-- output --
-- table: 004FBFF0
-- table: 004FBFF0
-- table: 004FBFF0
-- _A    =    table: 004FBFF0    table
-- _C    =    ccccc    string
-- _B    =    bbbbb    string
-- [Finished in 0.1s]

[参见]

http://blog.sina.com.cn/s/blog_4458fdda01012f4b.html

http://www.tuicool.com/articles/RVZvMbn

http://blog.csdn.net/maximuszhou/article/details/24105673?utm_source=tuicool

http://blog.csdn.net/ball32109/article/details/11402727
http://blog.codingnow.com/2011/12/lua_52_env.html
http://www.cnblogs.com/ringofthec/archive/2010/11/09/lua_State.html

 

--------------------------------------------------------------------------------------------------

2. C中遍历lua表结构

// 进行下面步骤前先将 table 压入栈顶 
int nIndex = lua_gettop( pLua );  // 取 table 索引值 
lua_pushnil( pLua );  // nil 入栈作为初始 key 
while( 0 != lua_next( pLua, nIndex ) ) 
{ 
 // 现在栈顶(-1)是 value,-2 位置是对应的 key 
 // 这里可以判断 key 是什么并且对 value 进行各种处理 
 lua_pop( pLua, 1 );  // 弹出 value,让 key 留在栈顶 
} 
// 现在栈顶是 table

lua_next() 这个函数的工作过程是

  1) 先从栈顶弹出一个 key(这也是为什么需要首先压入一个nil (lua_pushnil(pLua)) ) .

  2) 从栈指定位置的 table 里取下一对 key-value,先将 key 入栈再将 value 入栈

  3) 如果第 2 步成功则返回非 0 值,否则返回 0,并且不向栈中压入任何值  

第 2 步中从 table 里取出所谓“下一对 key-value”是相对于第 1 步中弹出的 key 的。table 里第一对 key-value 的前面没有数据,所以先用 lua_pushnil() 压入一个 nil 充当初始 key。  

注意:

  开始的时候先用 lua_gettop() 取了一下 table 在栈中的正索引(前面说过了,在进行这个 lua_next() 过程之前先将 table 入栈,所以栈大小就是 table 的正索引),后面的 lua_next() 过程中不断的有元素出入栈,所以使用正索引来定位 table 比较方便。  

  到了 table 中已经没有 key-value 对时,lua_next() 先弹出最后一个 key,然后发现已经没有数据了会返回 0,while 循环结束。所以这个 lua_next() 过程结束以后 table 就又位于栈顶了。

 

  问题概要: 用lua写了个函数,返回的是一个表.需要在C里对返回的表里元素做二次处理. 在C里我们可以通过lua_gettable()或者lua_rawget()来获取表里元素值,但使用这两个接口的前提是你得知道key,它才能给你 value. 当然对于顺序下标倒无所谓,但恰巧这次我用到的是关联数组,下标是无规则字符串.这时候如何遍历出表里元素就是个问题. lua_next()就成了比较合适的选择.

上图对简单的表遍历做了介绍, 但事实上的情况是我返回了一个二维表,如果你了解了lua_next()的处理过程,那下面的代码看起来就没什么问题了.

t_idx = lua_gettop(L);
lua_pushnil(L);
while (lua_next(L, t_idx))
{
    printf("============================\n");
    it_idx = lua_gettop(L);
    lua_pushnil(L);
    while(lua_next(L, it_idx))
    {
        printf("%s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
    }
    lua_pop(L, 1);
}

 [参见]  Lua 5.3 Reference Manual

posted @ 2015-02-05 15:47  小天_y  阅读(1555)  评论(0编辑  收藏  举报