以这种方式写作是否正常:
if(($x && $y && $z) eq "test"){
}
如果我对($x eq "test") && ($y eq "test") && ($z eq "test")
感兴趣?
答案 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;
}
原型&
和@
引用代码引用和参数列表。 YES
和NO
是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
关键字和代码块后的逗号。