双结构相等运算符:if(a == b == c)

Lan*_*Lan 17 java

我今天偶然写了一些代码,当Eclipse没有对我大喊大叫时,我感到很惊讶.代码对结构相等运算符(==)的双重使用类似于下面的if(a==b==c)结构.

public class tripleEqual {
    public static void main(String[] args) {
        boolean[] a = { true, false };
        boolean[] b = { true, false };
        boolean[] c = { true, false };

        for (int aDex = 0; aDex < 2; aDex++) {
            for (int bDex = 0; bDex < 2; bDex++) {
                for (int cDex = 0; cDex < 2; cDex++) {
                    if (a[aDex] == b[bDex] == c[cDex]) {
                        System.out.printf("Got a==b==c with %d %d %d\n", aDex, bDex, cDex);
                    }
                }
            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

输出是

Got a==b==c with 0 0 0
Got a==b==c with 0 1 1
Got a==b==c with 1 0 1
Got a==b==c with 1 1 0
Run Code Online (Sandbox Code Playgroud)

到处玩,我注意到我不能if(a==b==c)用任何类型,但是boolean.从那里布尔表达式是

( A'. B'. C') + ( A'. B . C ) + ( A . B'. C ) + ( A . B . C') 
Run Code Online (Sandbox Code Playgroud)

这简化为(A=B).'C + (A<>B).C.

因此,忽略副作用,if(a==b==c)等于if(a==b && !c) || (a!=b && c)).

任何人都可以解释if(a==b==c)语法如何表明?

编辑1:

我找到了困惑之后,很多人解释了左倾相关性.通常我会将'1'表示为true而将'0'表示为false,但是在上面的测试中我的最小化真值表/输出,我的'0'表示真,'1'表示假.否定表达( A'. B'. C') + ( A'. B . C ) + ( A . B'. C ) + ( A . B . C')(A=B)=C!

Dan*_*Dan 32

==运营商是向左结合,所以a == b == c被解释为(a == b) == c.所以a == b返回一个bool,然后进行比较c.

这是解析器的副作用,在实践中很少有用.正如你所观察到的那样,看起来它只做了一件事但做了一些非常不同的事情(所以即使它做了你想做的事情,也不建议这样做).有些语言实际上使==运算符不相关,因此a == b == c语法错误也是如此.

  • 我想补充一点,这个结构可以使用三个布尔值,但可能不会做OP所期望的.例如`true == false == false`将是'true`. (6认同)

aga*_*aga 9

到处玩,我注意到如果(a == b == c)除了布尔值之外的任何类型我都做不到.

您不能使用任何类型,但因boolean为此比较链将从左侧到右侧进行评估.第一次比较将简化为truefalse必须与链中的第三个值进行比较的值(此检查的结果将与第四个值进行比较,依此类推,直到链的末尾).至于原始值,你只能比较相同类型的基元(例如boolean和boolean将起作用,而double和boolean不会) - 这就是为什么你只能用布尔值来做 - 因为它==返回相同的值键入链中的所有值.
这里存在危险:所有比较链的结果与true您提供的所有值都不相等true.您可以从第二输出看看吧:true== false== false提高true,这是正确的结果,如果你从左至右(因为它在程序执行过程中发生的)评估,但可能似乎错了,如果你觉得这个比较链来一次性评估.正确的方法是执行两次显式比较:

if (a == b && b == c) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)