zoukankan      html  css  js  c++  java
  • lua中的闭包概念的学习笔记

    1、闭包的由来:

      个人理解,lua中之所以出现闭包的概念,完全是因为lua中允许函数的嵌套定义,并且在内嵌函数中使用了外包函数中定义的局部变量,例如c、c#就不允许函数的嵌套定义(但是允许函数的嵌套调用)

    以下是函数嵌套定义的一个例子:

    1 function fun1(n)
    2     local function fun2()
    3         print(n)
    4     end
    5 
    6     return fun2
    7 end

    fun1叫做fun2的外包函数,fun2叫做fun1的内嵌函数,并且这中内嵌与外包关系是允许传递的。什么意思呢?就是fun1的外包函数也是fun2的外包函数,fun2的内嵌函数也是fun1的内嵌函数。

    我们都知道,函数中定义的局部变量的生命周期就是在函数运行完后就结束了。假如现在有如下逻辑:

    1 fun3 = fun1(2048)
    2 fun3()

    执行结果如下:

    从执行结果上看,2048的生命周期好像不是在fun1执行完就结束的,看着像是在fun2执行完才结束的。事实是这样的吗?

     当fun3被调用时,其函数体访问了外部的局部变量n。当调用fun2函数时,创建fun2的fun1函数已经返回了,即执行结束,那么外部局部变量的生命周期也就结束了,这个时候在fun2中继续如何访问局部变量 n 呢?

    闭包就是为了解决这个问题出现的。

    其实不同的语言,对该问题有不同的处理方式,例如c、c#直接就不允许函数的嵌套定义,从根源避免问题的产生;python则是通过限定作用域来解决该问题。

    2、编译时: lua编译一个函数时,会为它生成一个原型(prototype) --- 包括 函数体对应的虚拟机指令、函数执行用到的常量、一些调试信息。

       运行时: 每当lua执行一个形如function...end 这样的表达式时,它就会创建一个新的数据对象,其中包含了相应函数原型的引用、环境(environment,用来查找全局变量的表)的引用以及一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。

       即函数是编译期概念,是静态的,而闭包是运行期概念,是动态的。

    3、词法定界:当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界。

       闭包的产生:调用了某种类型的外包函数产生的一个实例函数(类似上面的代码示例),这个外包函数满足,它的内嵌函数访问了在它中定义的局部变量。

       闭包组成:外部函数+外部函数创建的局部变量+内部函数(闭包函数)

    参考:https://blog.csdn.net/maximuszhou/article/details/44280109

      https://www.cnblogs.com/zzy-frisrtblog/p/5864209.html

      http://blog.chinaunix.net/uid-52437-id-2108789.html

  • 相关阅读:
    『实践』Yalmip建模+Cplex类求解(文末附程序、文章和算例)
    『实践』Matlab实现Flyod求最短距离及存储最优路径
    『转载』Matlab中fmincon函数获取乘子
    『实践』Yalmip获取对偶函数乘子
    『转载』hadoop 1.X到2.X的变化
    『转载』hadoop2.x常用端口、定义方法及默认端口
    『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现
    C#设计模式学习笔记:(6)适配器模式
    ASP.NET 开源导入导出库Magicodes.IE 导出Pdf教程
    Rx基础
  • 原文地址:https://www.cnblogs.com/luguoshuai/p/10049288.html
Copyright © 2011-2022 走看看