1. 调度表(dispatch table) tk图形用户界面工具包 my (@frames,@button); my %sub_of = ( "日志查询" => &push_button2 , "VIEW MEMORY" => &push_button2 , "VIEW DISK" => &push_button3 , 4 => sub{ print "program 4" }, 5 => sub{ print "program 5" }, 6 => sub{ print "program 6" }, 7 => sub{ print "program 7" }, 8 => sub{ print "program 8" }, 9 => sub{ print "program 9" }, ); 闭包(Closure) 闭包是这样一种子例程,创建时,它将包含其子例程的环境打包(包括所有它需要的和不局部与其本身的变量) 子例程引用 子例程并没有什么特别或神奇的地方,在这一节我们要学习如何创建对有名的和匿名的子例程的引用, 以及如何对它们进行间接访问 对有名子例程的引用: 我们前面就已经讲过,要创建对现存变量的引用,只需要给他加上反斜杠前缀。 对于子例程也大致如此,如&mysub 就是对&mysub的引用 sub greet() { print "hello "; } $rs=&greet; print &$rs; print " "; print "2222222222 "; my $str=&$rs(); print "$str is $str "; 对匿名子例程的引用: Vsftp:/root/perl/13# cat a6.pl $rs = sub { print "Hello "; }; print &$rs; print " "; Vsftp:/root/perl/13# perl a6.pl Hello 1 对子例程引用的间接访问: Vsftp:/root/perl/13# cat a7.pl $rs = sub { my $a=shift; my $b=shift; return $a + $b; }; print &$rs(10,20); print " "; print $rs->(10,20); print " "; Vsftp:/root/perl/13# perl a7.pl 30 30 ##定义下拉菜单 my %section = ( "1-系统信息查询" => ["日志查询","VIEW MEMORY","4"], "2-综合查询" => [1], "3-收起菜单" =>undef, ); my (@frames,@button); my %sub_of = ( "日志查询" => &push_button2 , "VIEW MEMORY" => &push_button2 , "VIEW DISK" => &push_button3 , 4 => sub{ print "program 4" }, 5 => sub{ print "program 5" }, 6 => sub{ print "program 6" }, 7 => sub{ print "program 7" }, 8 => sub{ print "program 8" }, 9 => sub{ print "program 9" }, ); 这段代码中的引用有些指向有名的子例程,有些则由于做的工作不多而直接以匿名子例程的形式嵌入其中。 闭包: 不仅可以返回数据,Perl 的子例程海可以返回一个指向子例程的引用. 这是一种涉及匿名子例程和词法变量(my)的隐含特性,考虑下面的例子: Vsftp:/root/perl/13# cat a8.pl $greeting ="hello world"; $rs = sub { print $greeting; }; &$rs(); print " "; Vsftp:/root/perl/13# perl a8.pl hello world 在这个例子中,匿名子例程利用了全局变量$greeting,没什么特别 Vsftp:/root/perl/13# cat a9.pl sub generate_greeting { my $greeting = "hello world"; return sub{print $greeting}; } $rs=generate_greeting(); &$rs(); print " "; Vsftp:/root/perl/13# perl a9.pl hello world 任何定义在匿名子例程中表达式当时就已经使用了$greeting. 一个子例程块,从另外的角度讲,就是一块在以后某个时候调用的代码, 因此它将保留所有要在以后使用的变量。(从某种意义上说就是把它带走) 当该子过程后来被调用并执行 print $greeting时,他会记得当初子例程创建时 变量$greeting的值。 让我们再来改动下这段代码, 以便更好地理解闭包这个专业用语究竟能做什么: Perl 创建的闭包恰好只针对(my) 词法变量而不对全局或者局部化(使用local)变量