加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua笔记

发布时间:2020-12-14 21:56:58 所属栏目:大数据 来源:网络整理
导读:1.lua_gettable void lua_gettable (lua_State *L,int index); 把 t[k] ?值压入堆栈,这里的? t ?是指有效索引? index ?指向的值,而? k ?则是栈顶放的值。这个函数会弹出堆栈上的 key,把结果放在栈上相同位置。 下面举个例子: // 将一个key放到栈顶,这个k
1.lua_gettable

void lua_gettable (lua_State *L,int index);

t[k]?值压入堆栈,这里的?t?是指有效索引?index?指向的值,而?k?则是栈顶放的值。这个函数会弹出堆栈上的 key,把结果放在栈上相同位置。

下面举个例子:

复制代码

// 将一个key放到栈顶,这个key为1。如果你的key是字符串,那就用lua_pushstring。

lua_pushnumber(L,1);

 table一开始是在栈顶,即-1处的,但上面的语句压入了一个值,栈顶变-2了。

 lua_gettable的作用就是以栈顶的值作为key来访问-2位置上的table。

lua_gettable(L,-2);

复制代码

这时table中的第1个元素的值就放到栈顶了,你想怎么使用就怎么使用吧。

获取table元素:

??*?将元素的key压入到栈中,用?lua_gettable(Lua_state,index)

??*?对于字符串索引,可以用lua_getfield(Lua_state,index,key)来直接获取,

  如:lua_getfield(stack,-1,"loaded");等价于 lua_pushstring(L,"loaded") lua_gettable(L,-2);

上面说的是访问table中的一个元素的方法,那要怎么样遍历table中的所有元素呢?

1)如果table是一个以连续的整形作为key的table, 可以用下面方法:

int size = lua_objlen(L,-1);相关于#table for(int i = 1; i <= size; i++) { lua_pushnumber(L,i); lua_gettable(L,128); line-height:1.5!important">2); 这时table[i]的值在栈顶了 lua_pop(L,把栈顶的值移出栈,保证栈顶是table以便遍历。 };

复制代码

2)如果table中的key是任意值呢?可以用下面的方法:

复制代码

lua_pushnill(L);  
while(lua_next(L,128); line-height:1.5!important">2))  
{  
这时值在-1(栈顶)处,key在-2处。  
lua_pop(L,0); line-height:1.5!important">把栈顶的值移出栈,让key成为栈顶以便继续遍历  
}  

复制代码

这里重点说明一下lua_next。

它执行操作是这样的,以栈顶元素为key,先判断上一个key的值(这个值放在栈顶,如果是nil,则表示当前取出的是table中第一个元素的值),然后得到当前的key和value。

这时先把栈顶出栈,将新key进栈,后将value进栈。这样栈顶就是table中第一个遍历到的元素的值。用完这个值后,我们要把这个值出栈,让新key在栈顶以便继续遍历。当根据上一个key值算不出下一个key值时(其实这时候key的是多少并不重要,只要不为nil就行,因为为nil会返回table的第一个元素),lua_next返回0,结束循环。

2.lua_settable
void lua_settable (lua_State *L,int index);

作一个等价于?t[k] = v?的操作, 这里?t?是一个给定有效索引?index?处的值,?v?指栈顶的值, 而?k?是栈顶之下的那个值。

这个函数会把键和值都从堆栈中弹出。

其实这个解释的意思就是,lua_settable 会把栈顶作为value,栈顶的下一个作为key设置到index指向的table,最后把这两个弹出弹出栈,这时候settable完成。

3:_G分析
??在Lua脚本层,Lua将所有的全局变量保存在一个常规的table中,这个table被称为全局环境,并且将这个table保存在一个全局变量_G中,也就是说在脚本中可以用_G获取这个全局table,并且有_G._G == _G,在默认情况,Lua在全局环境_G中添加了标准库比如math、函数比如pairs等。 
lua_pushglobaltable把这个全局环境压入栈中,在lua5.2 该函数实质就是从注册表中获取这个全局环境,即lua_pushglobaltable用下面宏定义的:?
#define lua_pushglobaltable(L) lua_rawgeti(L,LUA_REGISTRYINDEX,LUA_RIDX_GLOBALS)
这里的LUA_REGISTRYINDEX是Lua注册表(注册表是lua虚拟机范围内是全局唯一的)的伪索引,LUA_RIDX_GLOBALS是全局环境在注册表中的索引(也就说,全局环境_G是虚拟机范围内是全局唯一的)。?
 
4:lua_pushliteral和lua_pushstring有何区别?
通常在push字符串字面值时使用lua_pushliteral,在push字符串指针是使用lua_pushstring。 原因是前者通过sizeof(字符串字面值)/sizeof(char)计算长度,而后者通过strlen计算长度。 因此前者只能push字符串字面值,但速度比后者快。而后者既可push字符串字面值,也可push字符串指针。 
5:luaL_newmetatable
在lua代码中的普通表,不能作为userdata的metatable。必须使用luaL_newmetatable创建的表才能作为userdata的metatable。 

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读