2011-09-07 69 views
9

不知道Perl,我一直在友好的搜索引擎的帮助下增强Perl脚本。有没有一种更简洁的方式来有条件地'超越'这个Perl循环?

我发现我需要跳出循环的同时设定了标志,如果条件成真:

foreach my $element (@array) { 
    if($costlyCondition) { 
     $flag = 1; 
     last; 
    } 
} 

我知道更好的方式使用“最后一次”是这样的:

foreach my $element (@array) { 
    last if ($costlyCondition); 
} 

当然,这意味着虽然我可以享受语法糖,但我无法在循环中设置我的标志,这意味着我需要再次在外面评估$costlyCondition

有没有更干净的方法来做到这一点?

+6

后缀'if'确实只是一个语句。你的第一个更适用于一个条件的多条语句。 –

+0

我认为在这种情况下if块是更好的选择。循环控件上的后缀条件的通常参数是它将更重要的代码放在左边。强调循环对于那些退出条件有多个退出条件。在这种情况下,如果您使用了某些提供的复合表达式,则结果只是将循环控制更深地嵌入到表达式中,使其更难以一目了然。 –

+0

@Joel:你说得对。我留在原来的版本。 – ArjunShankar

回答

21

你可以使用一个do {...}块:

do {$flag = 1; last} if $costlyCondition 

可以使用,运营商加入语句:

$flag = 1, last if $costlyCondition; 

,你可以做同样的逻辑&&运营商:

(($flag = 1) && last) if $costlyCondition; 

或者即使较低优先级and

(($flag = 1) and last) if $costlyCondition; 

在一天结束的时候,有没有真正的理由做这些。它们都与您的原始代码完全相同。如果您的原始代码正常工作且清晰可辨,请保持原样。

+0

将'$ flag = 1和$ lastly $'添加到您的工具架中。你的第二个例子中的 –

+0

,放下{}。他们不需要。 – ysth

+0

我学习了一个新的perl构造! (做)。谢谢!就像你和几乎每个人都说的那样,最好让代码保持原样。 – ArjunShankar

5

一个想法是在子程序中执行循环,该子程序根据退出点返回不同的值。

my $flag = check_elements(\@array); 

# later... 

sub check_elements { 
    my $arrayref = shift; 
    for my $ele (@$arrayref) { 
    return 1 if $costly_condition; 
    } 
    return 0; 
} 
7

我同意弥敦道,虽然看起来整齐的代码是整齐的,有时一个可读的版本更好。只是为了它的地狱,但是,这里有一个可怕的版本:

last if $flag = $costly_condition; 

的使用注意事项,而不是平等==分配=的。该作业将返回$costly_condition中的任何值。

这当然不会让$flag = 1,但无论$costly_condition是。但是,既然这需要是真的,那么$flag。为了弥补这一点,你可以 - 作为扎伊德在评论中提到的 - 使用:

last if $flag = !! $costly_condition; 

如前所述,相当可怕的解决方案,但他们做的工作。

+4

'最后如果$ flag = !! $ costly_condition;'会做的伎俩;) – Zaid

+0

@zaid赫赫,是的,我也看到了。 – TLP

+0

使它更糟:除非$ flag =! $ costly_condition';) – pavel

0

这是可能的,但极不推荐:这样的技巧会降低代码的可读性。

foreach my $element (@array) { 
    $flag = 1 and last if $costlyCondition; 
} 
相关问题