什么是闭包,“This is a notion out of the Lisp world that says if you define an anonymous function in a particular lexical context, it pretends to run in that context even when it's called outside of the context.”【2】。在面向对象的语言里面,“A closure is a callable object that retains information from the scope in which it was created. From this definition, you can see that an inner class is an object-oriented closure, because it doesn’t just contain each piece of information from the outer-class object ("the scope in which it was created"), but it automatically holds a reference back to the whole outer-class object, where it has permission to manipulate all the members, even private ones.”【3】

先看这个例子:

#!/usr/bin/perl -w
use strict;{my $inc = 10;sub incr {print "$inc\n";$inc++;}
}incr();
incr();#prints:
#10
#11

这个例子说明命名函数默认是全局的,即使是定义在一个block里面。我们不能引用变量$inc,但是却可以调用函数。

#!/usr/bin/perl -w
use strict;sub make_incr {my $inc = shift;return sub { print "$inc\n"; $inc++ };
}my $c1 = make_incr(10);
my $c2 = make_incr(20);$c1->();
$c2->();
$c1->();
$c2->();#prints:
#10
#20
#11
#21

这个例子我们看到了,Perl的函数返回其实是一个匿名函数引用,这个就是magic所在了。这个也是Perl如何实现闭包的。

#!/usr/bin/perl -w
use strict;sub exclaim {my $prefix = shift;return sub { print "$prefix $_[0]!\n" };
}my $batman = exclaim('Indeed');
my $robin  = exclaim('Holy');$robin->('Mackerel');    # prints: Holy Mackerel!
$batman->('Robin');      # prints: Indeed Robin!

那么闭包有什么作用呢?以下摘自“Learning Perl Objects, References & Modules”的第6章【1】:

用法一 在subroutine中返回subroutine的引用,通常作为回调函数:

use File::Find;sub create_find_callbacks_that_sum_the_size {my $total_size = 0;return ( sub { $total_size += -s if -f }, sub { return $total_size } );
}my ( $count_em, $get_results ) = create_find_callbacks_that_sum_the_size();find( $count_em, "bin" );my $total_size = &$get_results();print "total size of bin is $total_size \n";

这段代码用于计算某个目录下所包含的所有文件的大小之和.

用法二  使用闭环变量作为输入,用作函数生成器,来生成不同的函数指针:

#!/usr/bin/perl -w
use strict;sub print_bigger_than {my $minimum_size = shift;return sub { print "$File::Find::name/n" if -f and -s >= $minimum_size };
}my $bigger_than_1024 = print_bigger_than(1024);
find( $bigger_than_1024, "bin" );

print_bigger_than在这里相当于一个函数生成器,不同的输入变量可以生成不同的函数指针.这里生成了一个可以打印出文件大小大于1024字节文件名的回调函数.

用法三 作为静态局部变量使用,提供了c语言静态局部变量的功能:

BEGIN {my $countdown = 10;sub count_down { $countdown-- }sub count_remaining { $countdown }
}

这里用到了关键字BEGIN. BEGIN的作用就是,当perl编译完这段代码之后,停止当前编译,然后直接进入运行阶段,执行BEGIN块内部的代码.然后再回到编译状态, 继续编译剩余的代码. 这就保证了无论BEGIN块位于程序中的哪个位置,在调用count_down之前,$countdown被确保初始化为10.

最后附上一个相当cool的例子,来在“Perl Best Practices”:

# Generate a new sorting routine whose name is the string in $sub_name
# and which sorts on keys extracted by the subroutine referred to by $key_sub_ref
sub make_sorter {my ( $sub_name, $key_sub_ref ) = @_;# Create a new anonymous subroutine that implements the sort...my $sort_sub_ref = sub {# Sort using the Schwartzian transform...return map { $_->[0] }                # 3. Return original valuesort     { $a->[1] cmp $b->[1] }    # 2. Compare keysmap { [ $_, $key_sub_ref->() ] }    # 1. Extract key, cache with value@_;                                 # 0. Perform sort on full arg list};# Install the new anonymous sub into the caller's namespaceuse Sub::Installer;caller->install_sub( $sub_name, $sort_sub_ref );return;
}# and then...
make_sorter( sort_sha => sub { sha512($_) } );
make_sorter( sort_ids => sub { /^ID:(\d+)/ } );
make_sorter( sort_len => sub { length } );# and later...
@names_shortest_first = sort_len(@names);
@names_digested_first = sort_sha(@names);
@names_identity_first = sort_ids(@names);

参考:

  1. http://blog.csdn.net/mac_philips/article/details/6058946
  2. http://unlser1.unl.csi.cuny.edu/faqs/perl-faq/Q3.14.html
  3. Think in Java, 4th
  4. http://www.itworld.com/nl/perl/08302001/
  5. http://docstore.mik.ua/orelly/perl/advprog/ch04_03.htm

Perl中的闭包(closure)相关推荐

  1. python中的闭包(closure)

    背景 本文尝试介绍Python中的闭包(closure),包括闭包是什么? 为什么要使用闭包?如何使用闭包? 嵌套函数及非局部变量 在介绍闭包之前,需要先明白什么是嵌套函数和非局部变量.在一个函数(f ...

  2. javascript中的闭包closure详解

    文章目录 简介 函数中的函数 Closure闭包 使用闭包实现private方法 闭包的Scope Chain 闭包常见的问题 闭包性能的问题 总结 简介 闭包closure是javascript中一 ...

  3. lua中的闭包(closure或者匿名函数)的作用

    闭包和upvalue lua构建一个新的函数时, 会创建一个函数对象, 其中包含了函数本身的原型还有函数使用到的外部变量或者常量. 当这个新的函数处于某个函数内部, 我们将这个对象称之为闭包, 它所引 ...

  4. 详解js中的闭包(closure)以及闭包的使用

    作用域链 我们知道在js中作用域分为全局作用域与局部作用域,作用域链的访问规则为从内到外,也就是说如果当前的作用域中没有该变量或者方法,则会在包含该作用域的外层作用域中,一层一层的向上找,直到wind ...

  5. python 返回函数 闭包_python中闭包Closure函数作为返回值的方法示例

    前言 首先看看闭包的概念:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外 ...

  6. python闭包的应用场景_简单谈谈Python中的闭包

    Python中的闭包 前几天又有人留言,关于其中一个闭包和re.sub的使用不太清楚.我在脚本之家搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善Python的内容. 1. 闭包的概念 首 ...

  7. [译]Javascript中的闭包(closures)

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  8. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )

    文章目录 总结 一.静态闭包变量 1.执行普通闭包变量 2.执行静态闭包变量 二. 在闭包中定义闭包 三. 完整代码示例 总结 在闭包中 , 打印 this , owner , delegate , ...

  9. 【Groovy】闭包 Closure ( 闭包调用 与 call 方法关联 | 接口中定义 call() 方法 | 类中定义 call() 方法 | 代码示例 )

    文章目录 总结 一.接口中定义 call() 方法 二.类中定义 call() 方法 三.完整代码示例 总结 在 实例对象后使用 " () " 括号符号 , 表示调用该实例对象的 ...

最新文章

  1. iOS之常用的正则表达式
  2. 打造 .NET Core 链接转发服务
  3. JavaScript学习笔记(七)--函数
  4. numpy 常用api(一)
  5. 2017蓝桥杯B组:最长公共子序列(动态规划详解(配图))
  6. span的title标签中的换行
  7. 手动打印日志及日志等级相关-1
  8. AlterID.exe解决teamview商业使用
  9. 【python快速入门】—唐宇迪课程笔记
  10. matlab 螺纹,关于螺纹边缘提取及参数测量
  11. Python 判断素数(质数)的方法讲解
  12. 鸟哥的Linux私房菜
  13. 理解RoIAlign实际操作
  14. Android专利战对大陆手机产业的影响
  15. 2023年了,推荐 5 款 API 管理工具
  16. 假设一个录像厅有0,1,2三种不同的录像片可由观众选择放映。录像厅的放映规则为: 1)任何时刻最多只能放映一种录像片,正在放映的录像片是自动循环放映的。最后一个观众主动离开时结束当前录像片的放映。
  17. 在阿里讲了5小时运营后,我想试着重新解读“运营”
  18. 「数字电子技术基础」2.数制和码制
  19. 7-5 查询自动售货机中商品的价格
  20. Python 数据分析微专业课程--项目03 视频网站数据清洗整理和结论研究

热门文章

  1. 无人机远距离WiFi图传应用,CV5200无线WiFi模组,远程实时通信传输方案
  2. 大学英语六级考试2023年6月
  3. python实战技能之数字求和
  4. 表的描述(键、码、候选码[关键字])
  5. Python计算山东新高考选考科目卷面原始成绩为等级成绩
  6. Comcast 力推 RDK
  7. stm32 模拟U盘IAP升级 与 FAT16文件系统
  8. 三层交换技术的理论与实现
  9. 2018苹果App上架App Store审核指南要求
  10. 第六章 网络编程-SOCKET开发