闭包有关的讨论

闭包有关的讨论

呵呵,既然flw老大都这么说了,那我也献一回丑,我的理解很肤浅并且不一定对,大家看看后忘了就好,不然误导了别人,我可担待不岂

[Copy to clipboard] [ - ]
CODE:
闭包 (closure):具有持续参照位于该函数范围之外的文字式变数值的能力。这些外部的文字变数会神奇地保留它们在闭包函数最初定义时的值.
#!/usr/bin/perl
sub make_saying {
my $salute = shift;
my $newfunc = sub {
my $target = shift;
print "$salute, $target!\n";
};
return $newfunc; # 返回一个闭合
}
$f = make_saying("Howdy"); # 创建一个闭合                -->这里$salute="Howdy"
$g = make_saying("Greetings"); # 创建另外一个闭合        -->这里$salute="Greetings"
# 到时...
$f->("world");                           --〉结果打印 Howdy world
$g->("earthings");                    --> 结果打印 Greetings earthings
这个例子摘自perl语言编程,我觉得他很有代表性。根据概念我们知道“闭合**持续参照**该函数范围之外的文字式变数值。这些外部的文字变数会神奇地**保留**它们在闭包函数最初定义时的值.”这里$salute是概念里面所说的“函数范围之外的文字式变数值”,也就是$salute一直保留到了闭合函数里,而后面的$target是闭合函数被赋与的新值。我们可以把$salute当作一个临时常量,在闭合里面他是不变的,后面只有一个变量,就是$target。
闭合看起来更像一个函数样版,保留一些空白,以便稍后添入内容。

这是我对闭合的理解。大家看过后就忘了。我理解的不一定对。
光这样说不够哦! 我觉得大家更想知道实际用途.
就像下面这个monk 写的帖子:
Why are closures cool?
http://www.perlmonks.org/?node_id=138195

大家有兴趣就去看看吧.
这个地方我一直觉得何伟平翻译的不好。没见过中文说的这么别扭的。
还有一点,(我个人意见,说错了请指正)
我觉得楼主举的例子是一个iterator,而不是一个closure.一个closure的例子:

{
my $cnt = 5;
  sub counter {
  return $cnt--;
}
  }

while(my $i = counter()) {
  print "$i\n";
}
print "BOOM!\n";

当然, iterator 会利用 closure这个trick,但是应该不能混为一谈.
以前我看perl语言编程3,闭包这一章一直没怎么看懂,除了译者的语言晦涩之外,主要是平时也不知道什么情形下用得上闭包。
现在再读一遍大家的文章,发现这个东西和我看过的OCaml中的高阶函数很相似。对于函数f(x1,x2,x3),确定其中的部分参数后,可以得到新的函数,如函数g=f(5,x2,x3)。
这个东西很有意思。好像High Order Perl这本书讲的就是如何让函数制造函数。
有时间再研究一下,跟大家讨论。


QUOTE:
原帖由 xiaoyafeng 于 2007-3-30 11:17 发表
还有一点,(我个人意见,说错了请指正)
我觉得楼主举的例子是一个iterator,而不是一个closure.一个closure的例子:

{
my $cnt = 5;
  sub counter {
  return $cnt--;
}
  }

while(my $i = counter ...

这个例子举的好,我用闭包实践的经验很少。闭包给我的感觉就是继承变量或表达式的值。不知道其他人有
什么见解。


QUOTE:
原帖由 royalzhang 于 2007-3-30 11:34 发表
以前我看perl语言编程3,闭包这一章一直没怎么看懂,除了译者的语言晦涩之外,主要是平时也不知道什么情形下用得上闭包。
现在再读一遍大家的文章,发现这个东西和我看过的OCaml中的高阶函数很相似。对于函数f(x ...

我试验了一下:

[Copy to clipboard] [ - ]
CODE:
sub test{
my $aaa=shift;
  sub {
    my $bbb=shift;
           sub {
             my $ccc=shift;
                     print $aaa."\n".$bbb."\n".$ccc."\n";
                 }
        }

}

my $f= &test("dddd");
$f->("cccc");
$f->("cccc")->("the last value");

结果:

[Copy to clipboard] [ - ]
CODE:
dddd
cccc
the last value



QUOTE:
原帖由 shhgs 于 2007-4-2 07:25 发表
closure的本意,其实是给别人一个窗口,让人家能访问到你自己。

Perl的grep是closure最好的例子。

[Copy to clipboard] [ - ]
CODE:
@l = grep {$_ % 2 == 0} (1..10);

这里,设计grep函数的时候,并不知道用户要根据什 ...

我觉得你说的这种情形称为“回调函数”更加合适一些。
8楼把callback和closure搞混了.
不过说老实话,我觉得map,和 grep设计很丑.如果能用引用就perfect.


ps.8楼签名太那个了吧?


QUOTE:
原帖由 xiaoyafeng 于 2007-4-2 11:10 发表

不过说老实话,我觉得map,和 grep设计很丑.如果能用引用就perfect.

的确应该这样。