第<4>章 子例程引用与闭包
来源:互联网 发布:始作俑者 其无后乎孟子 编辑:程序博客网 时间:2024/05/16 13:58
和普通变量一样,子例程(subroutine) 可以是有名的也可以是匿名的,而且Perl 语法上支持对任何一种类型的引用。对有名子例程的引用:我们前面已经讲过,要创建对现存变量的引用,只需给它加上反斜杠前缀。对子例程也大致如此,如\&mysub 就是对&mysub的引用,又比如:zjzc01:/root/hei# cat a24.pl sub greet { print "hello \n";};$rs = \&greet; #创建对子例程greet的引用&$rs;zjzc01:/root/hei# perl a24.pl hello zjzc01:/root/hei# cat a24.pl sub greet { print "hello \n";};$rs = \&greet;&$rs;$var=&$rs;print $var;print "\n";zjzc01:/root/hei# perl a24.pl hello hello 1该表达式的结果可能不是你所希望的,它调用greet,然后创建了一个对其返回值的引用也就是子例程中最后一个表达式的值是引用。由于print 最后执行并返回1或0(表明是否成功打印了后面的值),因此该表达式的结果就是一个对值为1或者0的标量变量的引用对匿名子例程的引用:你只需要省略掉子例程声明中的过程名即可创建匿名子例程。除了这一点外,其声明同有名字例程完全一样:zjzc01:/root/hei# cat a25.pl $rs = sub{print "hello\n";};$var= &$rs;print "111111111\n";print $var;print "\n";zjzc01:/root/hei# perl a25.pl hello1111111111zjzc01:/root/hei# cat a25.pl print sub{print "hello\n";};print "\n";print &{sub{print "hello\n";}};print "\n";zjzc01:/root/hei# perl a25.pl CODE(0x244a2f0)hello1 $client->on_receive_msg = sub{ my $msg = shift ;zjzc01:/root/hei# cat a25.pl $var= sub{print "hello\n";};print $var;print "\n";print &$var;print "\n";$x=&$var; print "\$x is $x\n";zjzc01:/root/hei# perl a25.pl CODE(0xa38320)hello1hello$x is 1对子例程引用的间接访问:对子例程引用的间接访问(dereference) 将会间接的调用该子例程。和数据引用一样,Perl并不关心$rs指向的有名还是无名的子例程,间接访问操作对两种情况都适合;使用子例程引用:让我们来看一些子例程引用的常见例子:回调函数与高级子例程my (@frames,@button); my %sub_of = ( "日志查询" => \&push_button2 , "温金短信查询" => \&push_button3 , "中均短信查询" => \&push_button4 , "机器信息查询" => \&push_button5, "IP信息查询" => \&push_button6, "设备信息维护" => \&push_button7, "test" => sub{ print "program 6" }, 7 => sub{ print "program 7" }, ##函数引用 8 => sub{ print "program 8" }, 9 => sub{ print "program 9" },);~ 回调函数就是通过引用来使用的普通子例程,调用者(那些引用使用者) 调度表:典型的调度表就是一个包含子例程引用的数组,下面的例子中,%options 就是一个将命令行选项映射到不同字例程的调度表:%options = ( ##针对每个选项调用相应的子例程"-h" =>\&help;"-f" =>sub{$askNoQuestions=1},"-r" =>sub{$recursive=1},"_default_" => \&default.);闭包:不仅可以返回数据,Perl的子例程还可以返回一个指向子例程的引用。这同其他别的传递子例程引用的方法没有什么不同,但是有一点是个例外,这是一种涉及匿名子例程和词法变量(my) 的隐含特性。考虑下面的例子:zjzc01:/root/hei# cat a26.pl $greeting = "hello world";$rs = sub{ print $greeting;};&$rs();print "\n";print "1111111111\n";$var=$rs;print $var;print "\n";print &$var;print "\n";zjzc01:/root/hei# perl a26.pl hello world1111111111CODE(0x718368)hello world1----------------------------------zjzc01:/root/hei# cat a26.pl $greeting = "hello world";$rs = sub{ return $greeting;};&$rs();print "\n";print "1111111111\n";$var=$rs;print $var;print "\n";print &$var;print "\n";zjzc01:/root/hei# perl a26.pl 1111111111CODE(0x1795368)hello world zjzc01:/root/hei# cat a27.pl sub generate_greeting{ my ($greeting) = "hello world"; return sub{print $greeting}; ##返回引用};$rs=&generate_greeting;print $rs;print "\n";print &$rs;print "\n";zjzc01:/root/hei# perl a27.pl CODE(0xeded48)hello world1闭包的应用:闭包以两种似乎毫无相关的方式来应用。最常见的方式就是用"智能调用"回调子例程由于闭包是一些包含少量私有数据的子例程引用,因此它们可以方便的应用在图形用户界面的回调过程中:闭包与对象的对比:对象通俗的定义是一组数据与函数的集合,数据提供对象函数操作的环境。比如,$buttion->setForeground("yellow")中, setForeground 函数会自动知道你指的是哪个按钮从某种意义上说,闭包也提供了同样的机制---它也是一种子例程与只对子例程可见的私有数据的结合。
0 0
- 第<4>章 子例程引用与闭包
- 子例程引用与闭包:
- 第四章 子例程引用与闭包
- 子例程引用和闭包
- 闭包与引用
- Perl_子例程调用by引用
- 第4章类与对象-引用包中的类-判断是否为三角形并计算其面积
- python 子包引用父包和其他子包
- Perl CH11 子例程与函数笔记
- 2Groovy闭包与方法引用
- MOOC清华《VC++面向对象与可视化程序设计》第4章:键盘操作例程(五个对话框)
- MOOC清华《VC++面向对象与可视化程序设计》第4章:鼠标操作例程(灰白选框)
- (欧) 第7章 指针与引用
- 第4章 引用计数
- C++双指针与指针引用详解例程
- 第五节 函数与闭包
- MOOC清华《VC++面向对象与可视化程序设计》第5章:位图资源例程
- MOOC清华《VC++面向对象与可视化程序设计》第5章:图标资源例程
- db2 连接的提示:未发出启动数据库管理器的命令
- 《Android源码设计模式解析与实战》读书笔记(十五)
- UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position ... 问题解决办法之一
- Android命名规范
- (转)Java中equals和==的区别
- 第<4>章 子例程引用与闭包
- VirtualBox CentOS6.3共享目录设置
- Could not launch "Zju_SmartHome",真机无法运行Xcode程序
- android 检查网络连接状态实现步骤<三>
- TCP连接的建立和终止
- 语义网格
- 反地理编码
- 粒子滤波的鼠标跟踪
- 探讨WaitForMultipleObjects如何突破64个句柄的限制