perl - 在 Perl 中使用 '||' 评估语句

标签 perl

有人可以解释一下这里发生了什么吗?

我已经尽可能地简化了。

( 1 || 2 == 1 )     is TRUE (as expected)
( 1 || 2 == 2 )     is TRUE (as expected)

我也希望以下都是正确的(但这可能表明缺乏理解......)
( 1 == ( 1 || 2 ) ) is TRUE  
( 2 == ( 1 || 2 ) ) is FALSE <--- !!! I don't understand this..

现在它开始变得有点奇怪......
( 2 == 1 || 2 )     is TRUE  
( 3 == 1 || 2 )     is TRUE  <--- !!! I don't understand this..

经过更多的玩耍,我发现以下内容:
( 1 == ( 1 || 2 ) ) is FALSE
( 2 == ( 1 || 2 ) ) is TRUE

( 1 == ( 1 && 2 ) ) is TRUE
( 2 == ( 1 && 2 ) ) is FALSE

您可能已经猜到我正在尝试按照以下方式做一些事情:
sub foo {
    # ... blah blah ...
    return 0 if $status == ( 2 || 4 || 7 || 9);
    # ... do other stuff ...
    return 1;
}

my $result = foo();
if ($result) { 
    # then do something based on a result
    } else {
    # log failure or whatever
}

我知道我可以使用这个习语,但额外的“$status”(es)似乎是多余的:
return 0 if ( $status == 1 || $status == 4 || $status == 7 ); # and so on...

我也知道我可以使用交替的正则表达式或检查值是否在允许值的数组中。

但我想了解为什么这不像我期望的那样。

最佳答案

$status == ( 2 || 4 || 7 || 9)

不会做你期望的。 (如果它确实按照您的预期运行,您认为 $status == (2 && 4 && 7 && 9) 应该是什么意思?)该语句等效于
$status == 2
||&&是始终返回其标量操作数之一的二元运算符。将它们视为等价于这些二元函数可能会有所帮助:
sub OR {
    my ($a,$b) = @_;
    if ($a) {
        return $a;
    } else {
        return $b;
    }
}

sub AND {
    my ($a,$b) = @_;
    if ($a) {
        return $b;
    } else {
        return $a;
    }
}

(我忽略了 ||&& 的短路特性,但这对这篇文章来说并不重要)。

注意到 ==具有比 || 更高的优先级和 && , 我们可以用 AND 重写你所有的表达式和 OR :
( 1 || 2 == 1 )     -->   (OR(1,2==1))  --->  OR(1,0) --> 1  TRUE
( 1 || 2 == 2 )     -->   (OR(1,2==2))  --->  OR(1,1) --> 1  TRUE

这两个表达式都是正确的,但不是您期望的原因。
( 1 == ( 1 || 2 ) ) -->   (1 == OR(1,2))   --->   (1==1) TRUE
( 2 == ( 1 || 2 ) ) -->   (2 == OR(1,2))   --->   (2==1) FALSE


( 2 == 1 || 2 )     -->   OR(2==1,2)   --->  OR(0,2) -->  2  TRUE  
( 3 == 1 || 2 )     -->   OR(3==1,2)   --->  OR(0,3) -->  3  TRUE


( 1 == ( 1 || 2 ) ) -->   (1==OR(1,2)) --->  (1==1)  TRUE, not FALSE
( 2 == ( 1 || 2 ) ) -->   (2==OR(1,2)) --->  (2==1)  FALSE, not TRUE

( 1 == ( 1 && 2 ) ) -->   (1==AND(1,2)) ---> (1==1) TRUE
( 2 == ( 1 && 2 ) ) -->   (2==AND(1,2)) ---> (2==1) FALSE

还有你最初的检查想法
$status == ( 2 || 4 || 7 || 9)

相当于
$status == OR(OR(OR(2,4),7),9)
$status == OR(OR(2,7),9)
$status == OR(2,9)
$status == 2

关于perl - 在 Perl 中使用 '||' 评估语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7823149/

相关文章:

perl - 访问数组中结构的字段

perl - 为什么带有方法修饰符的 Moose 角色应用程序在我的代码中不起作用?

具有最小值、最大值和默认值的 Perl Moose 属性

Perl HTML 解析器

perl - 如何将哈希中的数据存储在文件中并将其用于另一个哈希

perl - 警告-Perl中的 "Odd number of elements in hash assignment"

Python 相当于 Perl 的 HTTP::Async->next_response

java - 将各种不同的日期格式转换为一种通用的日期格式 Java 或 Perl

mysql 查询的 perl json 输出

arrays - 如何将 perl 哈希数组编码为未命名的 JSON 数组?