1 upvalue概念

upvalue:嵌套函数的外部函数的局部变量

function func(a) <== 这个函数返回值是一个函数

return function ()

a = a + 1    <== 这里可以访问外部函数func的局部变量a,这个变量a就是upvalue

return a

end

end

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

closure概念

closure: 一个匿名函数加上其可访问的upvalue

c = func(1) <== c现在指向一个拥有upvalue a = 1的匿名函数,c也被称作一个闭包

3 C函数如何向LUA递闭包

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n)
这个函数的作用是在栈上压入一个闭包,当一个c函数被创建时, 可以绑定几个值(第三个参数n表面)在它上面, 从而形成一个闭包.  在任何时刻调用这个c函数时, 都可以访问这几个绑定值
绑定的方法: 先一次压入要绑定的n个值到栈上, 然后调用lua_pushcclosure(L, fn, n)这样就形成的一个c闭

static int _counter (lua_State *L)

{

//

//获取第一个upvalue

//

double val = lua_tonumber(L, lua_upvalueindex(1));

lua_pushnumber(L, ++val);

/*

void lua_pushvalue (lua_State *L, int index);

把栈上给定索引处的元素作一个副本压栈。

*/

lua_pushvalue(L, -1);

/*

void lua_replace (lua_State *L, int index);

把栈顶元素放置到给定位置而不移动其它元素(因此覆盖了那个位置处的值),然后将栈顶元素弹出

*/

lua_replace(L, lua_upvalueindex(1));

return 1;  /* return new value */

}

static int counter (lua_State *L)

{

lua_pushnumber(L, 0);

//

//压入初始化第一个upvalue

//

lua_pushcclosure(L, &_counter, 1);

return 1;

}

void testlupvalue()

{

lua_State *L;

L = luaL_newstate();

luaL_openlibs(L);

lua_register(L, "counter", counter);

luaL_loadfile(L, "C:\\c.lua");

lua_pcall(L, 0,0,0);

lua_close(L);

}

closure

LUA upvalues的更多相关文章

  1. lua执行字节码的过程介绍

    前面一篇文章中介绍了lua给下面代码生成最终的字节码的整个过程,这次我们来看看lua vm执行这些字节码的过程. foo = "bar" local a, b = "a& ...

  2. lua解析脚本过程中的关键数据结构介绍

    在这一篇文章中我先来介绍一下lua解析一个脚本文件时要用到的一些关键的数据结构,为将来的一系列代码分析打下一个良好的基础.在整个过程中,比较重要的几个源码文件分别是:llex.h,lparse.h.l ...

  3. Lua string库整理

    string库提供了字符串处理的通用函数. 例如字符串查找.子串.模式匹配等. 当在 Lua 中对字符串做索引时,第一个字符从 1 开始计算(而不是 C 里的 0 ). 索引可以是负数,它指从字符串末 ...

  4. Lua与C的交互

    Lua 与 C 的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  ...

  5. Lua 5.1 参考手册

    Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 云风 译 www.codingno ...

  6. 在C函数中保存状态:registry、reference和upvalues

    C函数可以通过堆栈来和Lua交换数据,但有时候C函数需要在函数体的作用域之外保存某些Lua数据,那么我们想到全局变量或static变量,这样做的缺点是:(1)为Lua设计C函数库时,导致不可重入:(2 ...

  7. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  8. Lua基础

    局部定义与代码块: 使用local声明一个局部变量或局部函数,局部对象只在被声明的那个代码块中有效. 代码块:一个控制结构.一个函数体.一个chunk(一个文件或文本串)(Lua把chunk当做函数处 ...

  9. Lua函数之二

    Lua函数之二 Lua中函数的两个重要特性: 1.函数和其他类型(如number.string)一样,可以存放在变量中,也可以存放在table中,可以作为函数的参数,还可以作为函数的返回值. 2.嵌套 ...

随机推荐

  1. Java程序员的自我修养

    一.自我修养路线图 如图,这是笔者所走的路.且不论这路走的对不对,这个过程中行业环境会影响到你,大可不必钻牛角尖.附上这张图的目的是为了说,如果你想成为一个优秀的程序员,那么你一定要有规划.当然,别想 ...

  2. js时间格式化和相互转换

    1. Thu Mar 07 2019 12:00:00 GMT+0800 (中国标准时间) 转换为 2019-03-07 12:00:00 const d = new Date(Thu Mar 07 ...

  3. PLSQL 设置 里面timestamp显示的格式

    转自: https://blog.csdn.net/dietime1943/article/details/52672813# PL/SQL下timestamp日期显示格式问题 现象: 日期检索出来显 ...

  4. NLP使用pytorch框架,pytorch安装

    pytorch的安装方法及出现问题的解决方案: 安装pytorch,使用pip 安装,在运行代码的时候会报错,但是导包的时候不会报错,因此要采用conda的方式安装   1.找到miniconda的网 ...

  5. Centos7.6进入挂载硬盘后,进入应急模式(emergency mode)而非图形模式解决方法

    Centos7.6进入挂载硬盘后,进入应急模式(emergency mode)而非图形模式解决方法 话说某天我想在centos7.6中挂载个硬盘,结果刚在虚拟机中添加了一块硬盘,再次打开系统时,居然就 ...

  6. Python memory error的问题

    前段时间在读取一个文件的过程中,竟然出现了Memory Error!简直让我怀疑自己买了个假电脑,毕竟是8G内存i7处理器,一度怀疑自己装了假的内存条....下面说一下几个解题步骤....一般就是用下 ...

  7. HTML&CSS基础-ps的基本操作

    HTML&CSS基础-ps的基本操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   我们工作中可能会经常需要将一个图片做成一个网页,而图片中的字体大小,行间距,图中lo ...

  8. Zabbix监控平台-----深入理解zabbix

    一,Zabbix Web操作深入 (1)创建一个模版,所有的功能几乎都是在模版中定义的 点进新创建的模版查看,模版里几乎可以设定我们需要的所有功能 (2)在模版里创建应用集,应用集的作用就是将众多的监 ...

  9. k8s的pod

    一.Pod的分类 自主式Pod : 控制器管理的Pod:Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例.每个Pod都有一个特殊的被称为“根容器”的Pause容器. ...

  10. k8s的认证授权

    一.ServiceAccount Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的.它与User account不同   User acc ...