Perl:为什么应该;最后一句话;不用于退出grep或map?
关于上次的,请说出以下内容:Perl:为什么应该;最后一句话;不用于退出grep或map?,perl,Perl,关于上次的,请说出以下内容: last不能用于退出返回值的块,例如eval{}、sub{}或do{},并且不应用于退出grep()或map()操作 为什么要在grep()或map()中避免它?我对map特别好奇,因为它是foreach构造的另一种选择。文档似乎坚持在不描述后果的情况下不做任何事情。首先,要意识到grep和map对next、last和redo是透明的,就像if是透明的一样 $ perl -e' print "A"; for (8,9) { print "B"
last
不能用于退出返回值的块,例如eval{}
、sub{}
或do{}
,并且不应用于退出grep()或map()操作
为什么要在grep()或map()中避免它?我对map特别好奇,因为它是foreach构造的另一种选择。文档似乎坚持在不描述后果的情况下不做任何事情。首先,要意识到
grep
和map
对next
、last
和redo
是透明的,就像if
是透明的一样
$ perl -e'
print "A";
for (8,9) {
print "B";
print map { print "C"; next; print "D"; $_ } 1,2,3;
print "E";
}
print "F\n";
'
ABCBCF
但是文档并没有说不能使用last
退出map
,而是说不应该使用它。不清楚这是什么意思
- 不要认为它们会影响
和map
grep
- 不要这样使用它们,因为您的读者可能会认为它们会影响
和map
grep
- 不要这样使用它们,因为它会使Perl处于不稳定的状态
- 不要这样使用它们,因为将来行为可能会改变
next
、last
和redo
留下map
或grep
回调有什么不良副作用
有趣的是,使用循环构造保留map
和grep
甚至不会发出警告,即使以相同的方式保留子对象也会发出警告
$ perl -wE'while (1) { map { last; } 1; }'
$ perl -wE'while (1) { sub { last; }->(); }'
Exiting subroutine via last at -e line 1.
map
用于将一个列表映射到另一个列表。它当然不是foreach
的替代品。我经常看到这样的事情
map { print "$_\n" } @data;
它犯了使用map
作为其副作用并丢弃结果列表的错误。你不会考虑使用< /P>
my $x = 99;
sqrt(my $y = $x * $x);
print $y;
你会得到一个警告。出于同样的原因,当您指的是For
时,不应使用map
出于实际原因,请考虑
print "A";
print map { print "B"; last; print "C";} 1,2,3;
print "Z";
输出
AB
因此,在这种情况下,
last
退出整个程序。通常,在map
或grep
块中使用last
或next
会退出包含的块(如果有),否则会退出整个程序。这是需要避免的,因此“last
…不应用于退出grep()或map()操作”在Perl中,for/foreach、grep
和map
之间有相当多的功能重叠。然而,仅仅因为你可以使用它们来解决同一个问题,并不意味着它们都是完成特定工作的最佳工具(参见:使用螺丝刀敲打钉子)
:其目的是过滤列表并返回结果子集grep
:其目的是修改列表,并返回修改后的列表map
:它的目的是遍历列表并执行某些操作for/foreach
for/foreach
完成grep
和map
的每一次使用grep
和map
基本上是列表处理的特定用途(for/foreach
)的语法糖,它们特别常见和有用。通过设计、惯例和最佳实践,他们交易某些东西以增加便利性和清晰度
其中之一是grep
和map
旨在返回一个值。不鼓励在void上下文中使用它们,并认为这违反了惯用Perl。如果不返回值,请使用/foreach的
。如果返回值,则last
会中断该过程
如果您遵循Perl的最佳实践,那么使用
grep
和map
将始终返回一个值,这意味着应该避免使用last
。map将一个列表转换为另一个列表,因此每次map调用都应该返回一个元素。我得到的错误是不能“last”在循环块外部
尝试使用WinXP中的perl v5.14.1退出map
。@TLP:至少从perl v5.10.1开始就是这样。我猜这种“不应该”的语言是某种早期版本的Perl语言的延续,当时它一定导致了一些奇怪的行为。@TLP,你是说文档应该说不要在if
中使用last
?因为如果将last
放在if
@TLP中,会出现相同的错误,我一直使用last
退出if
状态<代码>而(1){x();如果(y()){last;}x();}。您可以使用map
执行相同的操作。但是医生说不要。为什么?我确信其意图是不应使用last
(和next
)退出map
或grep
中的隐式循环,因为它实际上退出了包含块。请特别注意,虽然文件级别的last
是非法的,打印“a”;打印地图{打印“B”;最后;打印“C”}1,2,3;打印“Z”代码>只打印AB
,因此退出整个程序。底线是,map
提供了从一个列表到另一个列表的映射,而不是像OP所说的那样,作为foreach
@Borodin的替代,Re“因为它实际上存在一个包含块”,是我提到的可能解释之一。这并不是文件实际所说的,你绝对没有提供任何证据来支持你的说法,这肯定是正确的解释。重新“特别注意”,那么为什么文档状态不使用last
退出if
的“then”块?它还退出一个“包含块”。你在反驳我的说法