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

  • 相关阅读:
    坑人的微信新版支付(V3.3.6)
    Chrome 实现前端页面自动刷新
    css基础
    基础HTML
    HTML5的世界
    Web前端开发的前景与用处
    JavaScript由浅入深(一)——类型、值和变量
    JS常用的方法总结
    js金钱分割,正则
    用 HTML5+ payment方法支付宝支付遇到的坑
  • 原文地址:https://www.cnblogs.com/luguoshuai/p/10049288.html
Copyright © 2011-2022 走看看