在同一个Perl语句中有条件运算符和后缀条件时会发生什么?

时间:2009-09-14 10:41:23

标签: perl syntax conditional-operator

有人可以解释一下这条线是如何工作的吗?

return $y < 0 ? - pip2 : pip2 if $x == 0;

如果$y <0返回-pip2,但是$y >= 0$x != 0时会返回什么?

此行来自此功能:

sub _atan {
    my( $y, $x ) = @_;

    return $y < 0 ? - pip2 : pip2 if $x == 0;
    return atan( $y / $x );
}

4 个答案:

答案 0 :(得分:20)

后缀“if”表示只有在条件为真时才执行return语句,所以

return $y < 0 ? - pip2 : pip2 if $x == 0;

相同
if ($x == 0)
{
    return $y < 0 ? - pip2 : pip2 ;
}

如果您对?:三元运算符感到困惑,可以将其重写为常规if语句,以产生此

if ($x == 0)
{
    if ($y<0)
    {
        return -pip2;
    }
    else
    {
        return pip2;
    }
}

答案 1 :(得分:7)

相同
if($x == 0){
  if($y<0){
    return -pip2;
  }else{
    return pip2;
  }
}

然后整个功能变为:

sub _atan {
  my( $y, $x ) = @_;
  if($x == 0){
    if($y<0){
      return -pip2;
    }else{
      return pip2;
    }
  }else{
    return atan( $y / $x );
  }
}

答案 2 :(得分:6)

这是难以阅读的代码的一个很好的例子。

让我们比较几种不同的方法来重写代码示例,看看我们如何保持简洁性和提高可读性。

这个三元版本仅为简洁而获胜,但仍难以阅读:

sub _atan {
    my( $y, $x ) = @_;

    return $x == 0 ? ($y < 0  ? -pip2 : pip2)
                   : atan( $y / $x );  
}

我发现链式条件运算符(?:)只有在后续运算符落入else位置时才可读:

sub _atan {
    my( $y, $x ) = @_;

    return $x != 0 ? atan( $y / $x ) : 
           $y < 0  ? -pip2           : pip2;  
}

仍然很简短,但可读性得到改善。

但使用ifunless怎么样?我们也可以使用简洁易读的代码吗?

就其本质而言,直接的if / else方法将更加冗长:

sub _atan {
    my( $y, $x ) = @_;

    my $atan;
    if( x == 0 ) {
        if( $y < 0 ) {
            $atan = -pip2;
        }
        else {
            $atan = pip2;
        }
    }
    else {
        $atan = atan( $y / $x )
    }            

    return $atan;  
}

通过以上内容很容易追踪,看看结果如何。因此可读性获胜,但简洁性受损。

我发现使用unlessif的语句修饰符形式提供了一种向一大块代码添加短路逻辑的简洁方法:

sub _atan {
    my( $y, $x ) = @_;

    return atan( $y / $x )
        unless $x == 0;

    return -pip2 if $y < 0;

    return pip2;  
}

这是可靠和可读的,但对我而言,似乎我们得到的回报超出了我们的需要。

因此,如果我们在混合中引入条件运算符,我们得到

sub _atan {
    my( $y, $x ) = @_;

    return atan( $y / $x )
        unless $x == 0;       

    return $y < 0  ? -pip2 : pip2;  
}

此表格与上述任何表格一样简洁,但更容易理解:

sub _atan {
    my( $y, $x ) = @_;

    return atan( $y / $x )
        unless $x == 0;

    return $y < 0  ? -pip2 : pip2;  
}

嵌套的if / else子句很难理解。在构建决策代码时要小心谨慎,这样可以大大提高可读性,从而提高可维护性,同时保留底层逻辑的简洁表达。

这里要解决的代码气味是条件运算符(?:)与语句修饰符形式if的巴洛克式组合。通过重新排列测试的顺序并仔细选择我们如何表示条件逻辑,我们能够保持简洁并澄清代码。

答案 3 :(得分:2)

用于解决问题的线太多会使代码难以维护(总是不得不滚动)。嵌套if的解决方案是4倍。想象一下,使用小4倍的屏幕。我最喜欢的语法是:

sub _atan {
    my ($y, $x) = @_;
    return atan ($y / $x) if $x != 0;
    return $y < 0  ? -pip2 : pip2;
}

如果将它们放在下一行,则可以减少使用后缀运算符的好处。 此行顺序(由@daotoad建议)允许将后缀条件放在更简单的行上。

初始语法也很好,但我不想处理包含以前帖子的建议嵌套的代码。