分享

深入理解Perl闭包及其应用

 herowuking 2015-07-31

本文和大家重点学习一下Perl闭包的概念,闭包(closure)是个精确但又很难解释的电脑名词。在Perl里面,Perl闭包是以匿名函数的形式来实现,具有持续参照位于该函数范围之外的文字式变数值的能力。

闭包的基本概念

闭包是可以包含自由(未绑定)变量的代码块;这些变量不是在这个代码块或者任何全局上下文中定义的,而是在定义代码块的环境中定义。“闭包”一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关变量引用没有释放)和为自由变量提供绑定的计算环境(作用域)。在Scheme、CommonLisp、Smalltalk、Groovy、JavaScript、Ruby和Python等语言中都能找到对闭包不同程度的支持。

Perl闭包

闭包(closure)是个精确但又很难解释的电脑名词。在Perl里面,Perl闭包是以匿名函数的形式来实现,具有持续参照位于该函数范围之外的文字式变数值的能力。这些外部的文字变数会神奇地保留它们在闭包函数最初定义时的值(深连结)。

如果一个程式语言容许函数递回另一个函数的话(像Perl就是),Perl闭包便具有意义。要注意的是,有些语言虽提供匿名函数的功能,但却无法正确处理闭包;Python这个语言便是一例。如果要想多了解闭包的话,建议你去找本功能性程式设计的教科书来看。Scheme这个语言不仅支援闭包,更鼓励多加使用。
以下是个典型的产生函数的函数:

  1. subadd_function_generator{  
  2. returnsub{shift+shift};  
  3. }  
  4. $add_sub=add_function_generator();  
  5. $sum=&$add_sub(4,5);#$sum现在是9了  

Perl闭包用起来就像是个函数样板,其中保留了一些可以在稍後再填入的空格。add_function_generator()所递回的匿名函数在技术上来讲并不能算是一个闭包,因为它没有用到任何位在这个函数范围之外的文字变数。

把上面这个例子和下面这个make_adder()函数对照一下,下面这个函数所递回的匿名函数中使用了一个外部的文字变数。这种指名外部函数的作法需要由Perl递回一个适当的闭包,因此那个文字变数在匿名函数产生之时的值便永久地被锁进闭包里。

  1. submake_adder{  
  2. my$addpiece=shift;  
  3. returnsub{shift+$addpiece};  
  4. }  
  5. $f1=make_adder(20);  
  6. $f2=make_adder(555);  

这样一来&$f1($n)永远会是20加上你传进去的值$n,而&$f2($n)将永远会是555加上你传进去的值$n。$addpiece的值会在闭包中保留下来。
Perl闭包在比较实际的场合中也常用得到,譬如当你想把一些程式码传入一个函数时:
my$line;
timeout(30,sub{$line=<STDIN>});
如果要执行的程式码当初是以字串的形式传入的话,即'$line=<STDIN>',那么timeout()这个假想的函数在回到该函数被呼叫时所在的范围後便无法再撷取$list这个文字变数的值了。
 

【编辑推荐】

  1. Perl encode函数用法
  2. Perl模式匹配参数使用详解
  3. 实例解析Perl多进程技术的应用
  4. 实例解析Perl命令行实用程序
  5. Perl多进程在自动化测试场景中应用

【责任编辑:程华权 TEL:(010)68476606】

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多