9

我并不真正了解 Perl,我一直在一个友好的搜索引擎的帮助下增强 Perl 脚本。

我发现如果条件满足,我需要在设置标志时跳出循环:

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

我知道使用“last”的更好方法是这样的:

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

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

有没有更清洁的方法来做到这一点?

4

4 回答 4

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;

归根结底,没有真正的理由去做这些。它们都与您的原始代码完全相同。如果您的原始代码有效且清晰易读,请保持原样。

于 2011-09-07T13:28:58.800 回答
7

我同意 Nathan 的观点,虽然看起来整洁的代码很整洁,但有时可读的版本会更好。不过,只是为了它,这是一个可怕的版本:

last if $flag = $costly_condition;

注意使用 assignment=而不是 equal ==。赋值将返回 中的任何值$costly_condition

这当然不会$flag = 1,但无论如何$costly_condition。但是,既然这需要是真的,那么$flag. 为了解决这个问题,您可以 - 正如 Zaid 在评论中提到的那样 - 使用:

last if $flag = !! $costly_condition;

如前所述,非常糟糕的解决方案,但它们确实有效。

于 2011-09-07T13:51:00.380 回答
5

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

my $flag = check_elements(\@array);

# later...

sub check_elements {
  my $arrayref = shift;
  for my $ele (@$arrayref) {
    return 1 if $costly_condition;
  }
  return 0;
}
于 2011-09-07T13:35:00.160 回答
0

这是可能的,但强烈不推荐:此类技巧会降低代码的可读性。

foreach my $element (@array) {
    $flag = 1 and last if $costlyCondition;
}
于 2011-09-07T20:06:04.453 回答