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

关于lua的闭包(Closure)和Upvalue

发布时间:2020-12-14 22:12:53 所属栏目:大数据 来源:网络整理
导读:关于lua的闭包(Closure)和Upvalue upvalue :嵌套函数的外部函数的局部变量 function func( a ) == 这个函数返回值是一个函数 return function () ??? a = a + 1??? == 这里可以访问外部函数func的局部变量a,这个变量a就是upvalue ??? return a? end end

关于lua的闭包(Closure)和Upvalue

upvalue:嵌套函数的外部函数的局部变量
function func(a) <== 这个函数返回值是一个函数
return function ()
??? a = a + 1??? <== 这里可以访问外部函数func的局部变量a,这个变量a就是upvalue
??? return a?
end
end

func返回一个匿名函数,可用变量接取之。该匿名函数有一个upvalue a(有点像C函数的static变量),初值为首次调用func时的参数

闭包:一个匿名函数加上其可访问的upvalue
c = func(1) <== c现在指向一个拥有upvalue a = 1的匿名函数,c也被称作一个闭包
c()????????? <== 返回2
c()????????? <== 返回3
c2 = func(1) <== c2现在指向另外一个拥有upvalue a = 1的匿名函数,c2也被称作一个闭包
c2()???????? <== 返回2

下面是示例代码:

int?
generatecclosure(lua_State *L)??????? /* 闭包产生器 */
{
??? lua_pushnumber(L,0);???????????? /* 压入第一个upvalue */?
??? lua_pushnumber(L,0);???????????? /* 压入第二个upvalue */
??? lua_pushcclosure(L,cclosure,2); /* 压入闭包的同时也把upvalue置入该闭包的upvalue表 */
??? return 1;???????????????????????? /* 返回闭包 */
}

int?
cclosure(lua_State *L)
{
??? double upval1,upval2;
??? upval1 = lua_tonumber(L,lua_upvalueindex(1)); /* 注意upvalue索引1,2是闭包依赖的,不会和其他的闭包中的索引冲突 */
??? upval2 = lua_tonumber(L,lua_upvalueindex(2));
??? upval1++; upval2++;????
??? lua_pushnumber(L,upval1); lua_replace(L,lua_upvalueindex(1));/* 更新upvalue1 */
??? lua_pushnumber(L,upval2); lua_replace(L,lua_upvalueindex(2));/* 更新upvalue2 */
??? lua_pushnumber(L,upval1 + upval2);
??? return 1;
}

int?
generatecclosure2(lua_State *L)????????
{
??? lua_pushnumber(L,10);?????????????
??? lua_pushnumber(L,10);?????????????
??? lua_pushcclosure(L,cclosure2,2);?
??? return 1;??????????????????????????
}

int?
cclosure2(lua_State *L)
{
??? double upval1,lua_upvalueindex(1));
??? upval2 = lua_tonumber(L,lua_upvalueindex(2));
??? upval1++; upval2++;
??? lua_pushnumber(L,lua_upvalueindex(1));
??? lua_pushnumber(L,lua_upvalueindex(2));
??? lua_pushnumber(L,upval1 + upval2);
??? return 1;
}

然后向lua虚拟机注册一下全局函数:

lua_register(L,"generatecclosure",generatecclosure);
lua_register(L,"generatecclosure2",generatecclosure2);

最后执行main.lua:

c = generatecclosure() c2 = generatecclosure2() print(c()) -- 2 print(c()) -- 4 print(c2()) -- 22 print(c2()) -- 24

(编辑:李大同)

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

    推荐文章
      热点阅读