"| ="是什么意思?(管道等运算符)

wts*_*g02 211 java android operators

我尝试使用Google搜索和Stack Overflow搜索,但它没有显示任何结果.我在开源库代码中看到了这个:

Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
Run Code Online (Sandbox Code Playgroud)

"| ="(pipe equal operator)是什么意思?

Den*_*ret 283

|=读取的方式与+=.

notification.defaults |= Notification.DEFAULT_SOUND;
Run Code Online (Sandbox Code Playgroud)

是相同的

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;
Run Code Online (Sandbox Code Playgroud)

其中|是逐位OR运算符.

这里引用所有运算符.

使用逐位运算符是因为,通常,这些常量使int能够携带标志.

如果你一下这些常数,你就会发现它们的权力是两个:

public static final int DEFAULT_SOUND = 1;
public static final int DEFAULT_VIBRATE = 2; // is the same than 1<<1 or 10 in binary
public static final int DEFAULT_LIGHTS = 4; // is the same than 1<<2 or 100 in binary
Run Code Online (Sandbox Code Playgroud)

因此,您可以使用按位OR来添加标志

int myFlags = DEFAULT_SOUND | DEFAULT_VIBRATE; // same as 001 | 010, producing 011
Run Code Online (Sandbox Code Playgroud)

所以

myFlags |= DEFAULT_LIGHTS;
Run Code Online (Sandbox Code Playgroud)

只是意味着我们添加一个标志.

并且对称地,我们使用&以下方法测试标志:

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;
Run Code Online (Sandbox Code Playgroud)

  • @DavidSchwartz见[this](http://stackoverflow.com/questions/12537661/adding-short-to-int/12537725#12537725) (6认同)
  • 就像`j + = 1;`与`j = j + 1;`相同. (2认同)
  • `boolean hasVibrate = DEFAULT_VIBRATE&myFlags;` - 你可以像Java那样从`int`翻译成`boolean`吗?这在C中是有效的,但我认为在Java中它必须写成`boolean hasVibrate =((DEFAULT_VIBRATE&myFlags)== DEFAULT_VIBRATE);` (2认同)
  • @DavidSchwartz 哇,与`+=` 的比较终于让我理解了它。谢谢! (2认同)

Gri*_*han 36

你的问题已经得到了足够的答案.但可能是我的回答可以帮助您更多地了解|=二元运算符.

我正在为按位运算符编写表:
以下是有效的:

----------------------------------------------------------------------------------------
Operator   Description                                   Example
----------------------------------------------------------------------------------------
|=        bitwise inclusive OR and assignment operator   C |= 2 is same as C = C | 2
^=        bitwise exclusive OR and assignment operator   C ^= 2 is same as C = C ^ 2
&=        Bitwise AND assignment operator                C &= 2 is same as C = C & 2
<<=       Left shift AND assignment operator             C <<= 2 is same as C = C << 2
>>=       Right shift AND assignment operator            C >>= 2 is same as C = C >> 2  
----------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

注意所有运算符都是二元运算符

请注意:( 对于以下几点,我想添加我的答案)

  • >>>是Java中的按位运算符,称为无符号移位
    >>>=不是Java中的运算符. >>> =运营​​商

  • ~是按位补码位,0 to 1 and 1 to 0(一元运算符)但~=不是运算符.

  • 另外, !调用逻辑非运算符,但!=检查两个操作数的值是否相等,如果值不相等则条件变为真.例如(A != B) is true.其中作为A=!B意味着如果BtrueA成为false(并且如果BfalseA成为true).

旁注:|不叫管道,而是叫做OR,管道是shell术语,将一个进程转移到下一个..

  • 我的印象是"管道"是角色的名称,这是shell术语的来源.但是,看看维基百科,它实际上被称为"垂直条",而"管道"则特定于shell命令.只想表示感谢添加旁注! (9认同)

dbr*_*rin 15

我正在寻找关于|=Groovy中的内容的答案,尽管上面的答案是正确的,但它们并没有帮助我理解我正在查看的特定代码片段.

特别是,当应用于布尔变量时,"| ="将在第一次遇到右侧的truthy表达式时将其设置为TRUE,并且对于所有| =后续调用将保持其TRUE值.像一个闩锁.

这是一个简单的例子:

groovy> boolean result  
groovy> //------------ 
groovy> println result           //<-- False by default
groovy> println result |= false 
groovy> println result |= true   //<-- set to True and latched on to it
groovy> println result |= false 
Run Code Online (Sandbox Code Playgroud)

输出:

false
false
true
true
Run Code Online (Sandbox Code Playgroud)

编辑:为什么这有用?

考虑一种情况,您想知道各种对象上是否有任何更改,如果是,请通知其中一个更改.所以,你要设置一个hasChanges布尔值并将其设置为 |= diff (a,b)然后|= dif(b,c)等.这是一个简短的例子:

groovy> boolean hasChanges, a, b, c, d 
groovy> diff = {x,y -> x!=y}  
groovy> hasChanges |= diff(a,b) 
groovy> hasChanges |= diff(b,c) 
groovy> hasChanges |= diff(true,false) 
groovy> hasChanges |= diff(c,d) 
groovy> hasChanges 

Result: true
Run Code Online (Sandbox Code Playgroud)

  • 是的,Java也是如此.但值得注意的是,这样的OR运算`y | = expr`不是短路**(不像`y = y || expr`),这意味着`expr`总是被评估.这对我来说并不是第一次明显:)所以在重构之前注意重要的是`y | =expr`↔`y= y || x`是**在语义上不等于**,如果`expr`实际上有副作用. (8认同)
  • 并且,考虑到这一点,_在您的情况下_使用 `hasChanges` _可能_最好选择 `y=y||x` 形式以从短路中受益,因为当您发现任何更改时,实际上并不需要这样做后续的差异,因为你已经知道答案。(在现实生活中尤其重要,因为比较的对象很复杂并且“区分”它们并不是很快) (2认同)
  • @FranklinYu 当然不是实现细节。在您引用的地方没有特别提到非短路,因为它不是特殊性 - 它是大多数运营商的默认和正常行为。其特殊性实际上是`||`和`&amp;&amp;`的短路,在相应部分[15.23](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15. html#jls-15.23) 和 [15.24](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.24) 规范中明确声明了这一事实,并且强调了与`|` 和`&amp;` 的区别。 (2认同)
  • @FranklinYu 所以我认为没有必要在下面你引用的部分 _(15.26.2 "Compund assignment operators")_ 中再次说明这一点,因为复合赋值总是非短路的(没有`| |=` 和 `&amp;&amp;=` 运算符会违反规则并需要特别提及)。 (2认同)

Til*_*lge 12

这是一个缩短:

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;
Run Code Online (Sandbox Code Playgroud)

并且|是一个有点明智的OR.


for*_*ord 8

|按位或运算符,它正在被应用+=.


woe*_*ens 5

注意:||= 不存在。(逻辑或)您可以使用

y= y || expr; // expr is NOT evaluated if y==true
Run Code Online (Sandbox Code Playgroud)

或者

y = expr ? true : y;  // expr is always evaluated.
Run Code Online (Sandbox Code Playgroud)

  • 不完全完整:您仍然可以将 `y |= expr` 与布尔值一起使用,它在 `y` 上给出与您的变体相同的结果,并重要说明**它不是短路**,这意味着 expr 始终是评估,即使在“y==true”的情况下 (11认同)