perl中的闭包使用
直接先上代码,看看示例一的实现:
示例一:
sub make_new_counter{
my $start = shift;
#返回匿名函数
return sub{
#自由变量
print $start++ ,"\n";
};
}
#代码分析:
#匿名函数的父函数是make_new_counter,两者间存在关联关系,同时匿名函数返回给了标量$from_zero,
#这个标量函数还存在于当前上下文中,内存并未释放,
#导致其关联的父函数make_new_counter调用栈也未被释放,因此计数start可以累加,
#类似于C语言中的state 关键字修饰局部变量`state int start = 0`
#返回匿名函数引用,并且这个匿名函数带有状态
my $from_zero = make_new_counter(0);
my $from_three = make_new_counter(3);
#从零开始的计时器
$from_zero->();
$from_zero->();
#从三开始的计时器
$from_three->();
$from_three->();
运行结果:
0
1
3
4
闭包概念
闭包就是能够读取其他函数内部变量的函数,如上述代码中的匿名函数。
闭包特征
判断是否是闭包,可以看以下两个关键点:
- 没有被创建它的上下文销毁
- 引用了自由变量
自由变量就是没有在函数块中定义,也没有从arguments中送入,也不在全局上下文中定义的这些变量,如上述代码中的start。
闭包作用
闭包可以用在许多地方。它的最大用处有两个:
- 让这些变量的值始终保持在内存中,如示例一
- 读取函数内部的变量,如示例二
示例二:
sub city_name{
my $city_name = "Fuzhou";
return sub{ print $city_name };
}
my $city = city_name();
#正常情况下,局部变量$city_name在函数调用结束后,对应的调用栈已经释放,无法正常访问,
#但是由于闭包的引入,使得$city_name一直存在于内存中,并未被释放,所有可以正常访问;
print "name:",$city->();#输出Fuzhou
闭包劣势
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会影响性能。