是否有一种更清洁的方式来有条件地"持续"出这个Perl循环?

Arj*_*kar 9 perl syntactic-sugar

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

我发现如果条件成立,我需要在设置标志时突破循环:

foreach my $element (@array) {
    if($costlyCondition) {
        $flag = 1;
        last;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

foreach my $element (@array) {
    last if ($costlyCondition);
}
Run Code Online (Sandbox Code Playgroud)

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

有更清洁的方法吗?

Nat*_*man 21

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

do {$flag = 1; last} if $costlyCondition
Run Code Online (Sandbox Code Playgroud)

您可以使用,运算符来加入语句:

$flag = 1, last if $costlyCondition;
Run Code Online (Sandbox Code Playgroud)

您可以对逻辑&&运算符执行相同的操作:

(($flag = 1) && last) if $costlyCondition;
Run Code Online (Sandbox Code Playgroud)

甚至是较低的优先级and:

(($flag = 1) and last) if $costlyCondition;
Run Code Online (Sandbox Code Playgroud)

在一天结束时,没有任何理由去做这些.它们都与原始代码完全相同.如果您的原始代码有效并且清晰易读,请保持原样.


TLP*_*TLP 7

我同意Nathan的看法,虽然整洁的代码很整洁,但有时可读的版本更好.尽管如此,这是一个可怕的版本:

last if $flag = $costly_condition;
Run Code Online (Sandbox Code Playgroud)

注意使用赋值=而不是相等==.赋值将返回任何值$costly_condition.

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

last if $flag = !! $costly_condition;
Run Code Online (Sandbox Code Playgroud)

如上所述,非常可怕的解决方案,但他们确实有效.

  • `如果$ flag = !! $ expensive_condition;`会做的伎俩;) (4认同)

Bil*_*ert 5

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

my $flag = check_elements(\@array);

# later...

sub check_elements {
  my $arrayref = shift;
  for my $ele (@$arrayref) {
    return 1 if $costly_condition;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)