Perl逻辑和多个测试

时间:2014-03-30 20:17:05

标签: perl if-statement logical-operators

以这种方式写作是否正常:

if(($x && $y && $z) eq "test"){

}

如果我对($x eq "test") && ($y eq "test") && ($z eq "test")感兴趣?

3 个答案:

答案 0 :(得分:4)

它不会是正常的,因为它甚至不起作用

$x && $y会返回$x$y,具体取决于$x的值是否为真。

这意味着($x && $y) && $z会返回$x$y$z,具体取决于$x$y的值。

这意味着$x$y$z中只有一个会与'test'进行比较。

例如,当你有$x='abc'; $y='def'; $z='test';时,你会得到误报(当​​它应该返回false时返回true)。

如果你想要更短的东西,那么你必须使用像

这样的东西
use List::MoreUtils qw( all );

if ( all { $_ eq "test" } $x, $y, $z )

答案 1 :(得分:1)

没有

表达式$x && $y && $z等同于表达式

$x ? $x : $y ? $y : $z

将与eq运算符另一侧的表达式分开计算。

正如你所做的那样写if ($x eq 'test' && $y eq 'test' && $z eq 'test') ...就像你将要得到的那样合理简洁。

答案 2 :(得分:1)

作为ikegami's answer的详细说明,我想我会展示all()子程序的代码,因为它很简单,并且很好地证明了问题答案背后的逻辑。而且,正如它发生的那样,可以很好地证明prototypes如何运作。

sub all (&@) {
    my $f = shift;
    foreach ( @_ ) {
        return NO unless $f->();
    }
    return YES;
}

原型&@引用代码引用和参数列表。 YESNO是true和false的常量,定义如下:

# Use pure scalar boolean return values for compatibility with XS
use constant YES => ! 0;
use constant NO  => ! 1;

这个子程序的基本要点是采用代码引用(匿名子程序)并对每个参数执行一次,使用$_作为循环变量。如果任何参数导致代码块返回false值,则子例程返回false并结束。

使用此代码和这些原型,我们可以像map一样使用all子例程,首先使用代码块:

all { $_ eq "foo" } "foo", "bar", "baz";

如果我们删除原型(&@),我们必须将代码引用作为独立的代码引用,作为列表的一部分:

all sub { $_ eq "foo" }, "foo", "bar", "baz";

请注意添加sub关键字和代码块后的逗号。