正确使用简短形式的"如果"在perl

时间:2014-05-19 13:21:25

标签: perl

我在perl中使用if的简短形式编写了一系列perl结构,如下所示,

    ( $psap[0] = sprintf( "%.4f", $psap[0] )
 && ( $psap[0] = "1:" . $psap[0] )
 && push( @all, $psap[0] ) )
            if ( defined( $psap[0] ) );

    ( $psap[1] = sprintf( "%.4f", $psap[1] )
 && ( $psap[1] = "2:" . $psap[1] )
 && push( @all, $psap[1] ) )
            if ( defined( $psap[1] ) );

我遇到了一些问题,

  1. sprintf似乎不起作用(值未舍入);

  2. 当我尝试print $psap[0] and $psap[1]值时,我只是分别获得了1 and 2而没有其他内容(@all包含psap[0]的值,如预期的那样);

  3. 我同意代码不可读,我想要一些快速解决问题的方法。后来我写了if的完整形式,它按预期工作。

4 个答案:

答案 0 :(得分:4)

忘掉if ......它是一只红鲱鱼。专注于此:

$psap[1] = sprintf( "%.4f", $psap[1] )
   && ( $psap[1] = "2:" . $psap[1] )
   && push( @all, $psap[1] )

基本上是这样的:

$psap[1] = X() && Y() && Z();

所以你要将$psap[1]设置为对三个操作数的布尔&&操作的结果。

将作业包装在括号中,如下所示:

( $psap[1] = sprintf("%.4f", $psap[1]) )
&& ( $psap[1] = "2:" . $psap[1] )
&& push( @all, $psap[1] )

或使用低优先级and运算符:

$psap[1] = sprintf("%.4f", $psap[1])
and $psap[1] = "2:" . $psap[1]
and push(@all, $psap[1])

答案 1 :(得分:3)

您的代码是对if语句修饰符的可怕滥用,除了最简单的语句之外,它永远不会控制任何内容。

我建议你像这样编码,这更清楚

for my $i (0, 1) {
  next unless defined $psap[$i];
  $psap[$i] = sprintf '%d:%.4f', $i + 1, $psap[$i];
  push @all, $psap[$i];
}

答案 2 :(得分:1)

$psap[0] is of lower precedence than the &&的作业,因此会为其分配

的值
sprintf( "%.4f", $psap[0] ) && ( $psap[0] = "1:" . $psap[0] ) && push( @all, $psap[0] )

将它包装在一些额外的括号中:

#!/usr/bin/env perl

use strict;
use warnings;

my @psap = ( 0.123456789 );
my @all;

( ( $psap[0] = sprintf( "1:%.4f", $psap[0] ) )
    && push( @all, $psap[0] ) 
)
if ( defined( $psap[0] ) );

print $psap[0], "\n";

我也冒昧地将“1:”放入sprintf而不是分两步建立字符串。

operator precedence and associativity table所示,and的优先级要低得多,可以改为使用:

$psap[0] = sprintf( "1:%.4f", $psap[0] ) and push( @all, $psap[0] ) 
    if ( defined( $psap[0] ) );

输出:

1:0.1235

答案 3 :(得分:1)

如果您不想依赖于他们的结果,并且只想依次执行您的代码,则应该避免使用逻辑运算符,因此

$psap[1] = sprintf("%.4f", $psap[1]), $psap[1] ="2:$psap[1]", push(@all, $psap[1])
  if defined $psap[1];

或更短,

defined and $_ = sprintf("%.4f", $_), $_ ="2:$_", push(@all, $_)
  for $psap[1];

或更短,

defined and $_ = sprintf("2:%.4f", $_), push(@all, $_)
  for $psap[1];