在Java中,我真的想知道使用a += b;
或a = a + b;
之间是否存在差异。我应该主要使用哪一个?我知道第一个是快捷方式,但编译器是否会以不同的方式获得这两个指示?
答案 0 :(得分:16)
请参阅Java language specification, 15.26.2 Compound assignment operators
引用相关部分:
形式E1 op = E2的复合赋值表达式是等价的 到E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1 仅评估一次。
short x = 3;
x += 4.6;
并导致x的值为7,因为它相当于:
short x = 3;
x = (short)(x + 4.6);
因此它不仅仅是语法糖,而是
int x = 1;
long a = 2l;
x+= a;
编译,其中
int x =1;
long a =2l;
x = x+a;
给出了编译错误,如here on StackOverflow quite recently
所述答案 1 :(得分:3)
我知道大多数语言中的语法糖,包括c,c ++,C#,java,javascript ..
Cicada关于 c ++ 注意到的显着差异:
在数字类型(int和friends)上没有区别。 在用户定义的类上可能存在差异。 例如,值得注意的是来自DirectX的D3DXVECTOR3。 使用+会构造一个临时对象,而+ =则不会。 后者的速度提高了约30%。
答案 2 :(得分:3)
它确实取决于语言,但在c#中使用+ = b;效率稍高。
a仅评估一次。
在a = a + b中,a被评估两次。
答案 3 :(得分:2)
除了上述所有内容外,您还可以使用以下快捷方式:
运营商(+ =)
x+=y;
与:
相同x=x+y;
运营商( - =)
x-=y;
与:
相同x=x-y;
运营商(* =)
x*=y;
与:
相同x=x*y;
运营商(/ =)
x/=y;
与:
相同x=x/y;
运营商(%=)
x%=y;
与:
相同x=x%y;
运营商(& =)
x&=y;
与:
相同x=x&y;
运营商(| =)
x|=y;
与:
相同x=x|y;
运营商(^ =)
x^=y;
与:
相同x=x^y;
运营商(>> =)
x>>=y;
与
相同result=x>>y;
对运营商(<< =)和运营商(>>> =)的相同操作。
答案 4 :(得分:1)
在大多数情况下,它最终会成为同一件事。
在某些语言中+=
是一个单独的运算符,可以重载以执行不同的操作。
例如在带有列表的Python中,行为是不同的(我学到了很多方法)
a = [1]
b = [2]
z = a
a = a + b
#z is not modified
a = [1]
b = [2]
z = a
a += b
# z is modified
答案 5 :(得分:1)
在大多数支持此注释的语言中,a = a + b
与a += b
相同,但情况并非总是如此。
以下是Python中的一个示例(使用Numpy):
>>> import numpy as np
>>> a = np.array([1])
>>> b = np.array([2])
>>> c = a
>>> a = a + b
>>> print a
[3]
>>> print c
[1]
此处a = a + b
为a + b
创建一个新数组,并将其存储到a
中。 c
使用与初始a
相同的引用仍保留初始数组(值为1)。
>>> a = np.array([1])
>>> b = np.array([2])
>>> c = a
>>> a += b
>>> print a
[3]
>>> print c
[3]
此处a += b
重新使用初始数组a
。因此,由于a
和c
都引用相同的数组,因此a
和c
都会被修改。
答案 6 :(得分:1)
我更喜欢a += b
而不是a = a + b
。首先,它写得更少,其次更清楚的是发生了什么。在谈论C ++和类时,使用+ =可能更有效。看一下这个样本:
class C {
public:
const C &operator =(const C &rhs) { printf("=\n"); x = rhs.x; return *this; }
C operator +(const C &rhs) { printf("+\n"); C c; c.x = x + rhs.x; return c; }
C &operator +=(const C &rhs) { printf("+=\n"); x += rhs.x; return *this; }
int x;
};
C a, b;
a.x = 1;
b.x = 2;
a += b; // same as a.operator+=(b)
a = a + b; // same as a.operator=(a.operator+(b))
正如您在operator +=
中所看到的,您拥有的临时对象更少,性能也更好。
答案 7 :(得分:0)
编译器 - (以及实现 - )定义编译器是否从上述源生成不同的代码,但有一点是肯定的:a + = b应该是a = a + b的更简单的简写符号。 (这就是为什么一般来说,理智的编译器会为两者生成相同的代码。)
答案 8 :(得分:0)
不,编译器不区分输出中的两个。唯一的区别在于解析和可能在词法分析中(取决于扩展)。您通常会使用快捷方式+=
。这只是语法糖。