为什么x ==(x = y)与(x = y)== x不同? [英] Why is x == (x = y) not the same as (x = y) == x?

查看:162
本文介绍了为什么x ==(x = y)与(x = y)== x不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下示例:

class Quirky {
    public static void main(String[] args) {
        int x = 1;
        int y = 3;

        System.out.println(x == (x = y)); // false
        x = 1; // reset
        System.out.println((x = y) == x); // true
     }
}

我不确定Java语言规范中是否有一项规定要加载变量的先前值以便与右侧(x = y)进行比较,该变量应按照方括号中的顺序进行计算首先.

为什么第一个表达式的计算结果为false,而第二个表达式的计算结果为true?我希望(x = y)首先得到评估,然后将x与自身(3)进行比较并返回true.


此问题不同于 Java表达式,因为在这里x绝对不是子表达式".需要进行加载以进行比较,而不是对其进行评估".这个问题是特定于Java的,而x == (x = y)表达式不同于通常为棘手的面试问题而精心设计的牵强附会的结构,它来自一个实际项目.它原本应该是一键替换"成语的单行替换法

int oldX = x;
x = y;
return oldX == y;

比x86 CMPXCHG指令甚至更简单的指令,在Java中都应使用较短的表达式.

解决方案

应按照括号中的顺序先计算

不.一个普遍的误解是括号对计算或评估顺序有任何(一般)影响.它们仅将表达式的各部分强制转换为特定的树,将正确的操作数绑定到作业的正确操作.

(而且,如果您不使用它们,则此信息来自运算符的优先级"和关联性,这是语言的语法树如何定义的结果.实际上,这仍然是它的确切用法.当您使用括号时可以使用,但是我们简化了一点,说我们当时不依赖任何优先级规则.)

一旦完成(即,一旦您的代码被解析成程序),那些操作数仍然需要进行评估,并且关于如何完成这些操作有单独的规则:所述规则(如安德鲁向我们展示的那样)表明LHS首先用Java评估每个操作.

请注意,并非所有语言都如此.例如,在C ++中,除非您使用&&||之类的短路运算符,否则通常不指定操作数的求值顺序,并且您不应以任何方式依赖它.

教师需要停止使用误导性短语(例如使加法首先发生")来解释运算符的优先级.给定表达式x * y + z,正确的解释是运算符优先级使加法发生在x * yz之间,而不是在yz之间",而没有提及任何顺序".

Consider the following example:

class Quirky {
    public static void main(String[] args) {
        int x = 1;
        int y = 3;

        System.out.println(x == (x = y)); // false
        x = 1; // reset
        System.out.println((x = y) == x); // true
     }
}

I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.

Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.


This question is different from order of evaluation of subexpressions in a Java expression in that x is definitely not a 'subexpression' here. It needs to be loaded for the comparison rather than to be 'evaluated'. The question is Java-specific and the expression x == (x = y), unlike far-fetched impractical constructs commonly crafted for tricky interview questions, came from a real project. It was supposed to be a one-line replacement for the compare-and-replace idiom

int oldX = x;
x = y;
return oldX == y;

which, being even simpler than x86 CMPXCHG instruction, deserved a shorter expression in Java.

解决方案

which, by the order implied by brackets, should be calculated first

No. It is a common misconception that parentheses have any (general) effect on calculation or evaluation order. They only coerce the parts of your expression into a particular tree, binding the right operands to the right operations for the job.

(And, if you don't use them, this information comes from the "precedence" and associativity of the operators, something that's a result of how the language's syntax tree is defined. In fact, this is still exactly how it works when you use parentheses, but we simplify and say that we're not relying on any precedence rules then.)

Once that's done (i.e. once your code has been parsed into a program) those operands still need to be evaluated, and there are separate rules about how that is done: said rules (as Andrew has shown us) state that the LHS of each operation is evaluated first in Java.

Note that this is not the case in all languages; for example, in C++, unless you're using a short-circuiting operator like && or ||, the evaluation order of operands is generally unspecified and you shouldn't rely on it either way.

Teachers need to stop explaining operator precedence using misleading phrases like "this makes the addition happen first". Given an expression x * y + z the proper explanation would be "operator precedence makes the addition happen between x * y and z, rather than between y and z", with no mention of any "order".

这篇关于为什么x ==(x = y)与(x = y)== x不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆