曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5333|回复: 0
打印 上一主题 下一主题

[OOP] 闭包

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2011-10-28 14:46:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
闭包是指“一个带有数据(attitude)的匿名子例程(匿名子函数),也可以称作”inside-out objects"。

对象是附有子例程的数据,而闭包则是附带有一些数据的子例程。

在 Perl 中,对象简单的说就是一个散列表,而散列表正是一些数据,而操作一个对象则需要用它所从属的包(类)中的方法进行,而这些方法实际就是一些子例程。

下面代码演示了一个简单的闭包:
[code=perl]#!/usr/bin/perl


my $name = "Jasmine";


{     # 闭包
        my $name = "King";
        my $age  = 25;


        $ref = sub { return "$name is $age. \n"; }
}
print "$name is back\n";
print &{$ref};[/mw_shl_code]
运行输出:
$ ./exp1.pl
Jasmine is back
King is 25.
第 1 句输出中的 $name 就是外围的 Jasmine ,这点是显而易见的。
程序中,$ref 是一个匿名子例程的指针,&{$ref} 这种方式是通过指针来调用子例程。注意,在闭包内有两个 my 变量($name 和 $age)。在非闭包的使用情况下,在代码块(花括号之外)外是看不到这两个变量的,然而在闭包的使用方式中,即使是在代码块外调用,该子例程(匿名子例程,即闭包)也能访问这两个变量。之所以外部能访问闭包内的词法变量,正是因为 $ref 这个引用要访问它们,除非不再引用这些变量,否则 Perl 不会清除它们的。如果你在 $ref 前面也用一个 my 来声明,那么引用也就会出错了。从这里可以看出,$ref 就像是一根通往闭包内的探针。

再考虑下面的一个例子:
[code=perl]#!/usr/bin/perl


sub paint {
        my $color = shift;


        my $ref = sub {
                my $object = shift;
                print "Paint the $object $color.\n";
        };
        return $ref;
}


my $p1 = paint("red");
my $p2 = paint("blue");


$p1->("flower");
$p2->("sky");[/mw_shl_code]
运行输出:
$ ./exp2.pl
Paint the flower red.
Paint the sky blue.
在上面程序中,分别以不同的参数调用了同一个 paint() 子例程,每次调用时,Perl 都会为其创建一个新的词法变量 $color ,并赋予该变量独立的值。变量 $color 会包含在返回的那个闭包中。指针 $p1 和 $p2 指向的是匿名子例程的引用,它们各自形成一个“闭包”,其中分别含有在 paint() 中定义的变量 $color,并可以各自访问该变量在本闭包中的副本,直到变量不再被引用为止。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-6 01:25 , Processed in 0.073659 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表