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


248

我尝试使用Google搜索和堆栈溢出进行搜索,但未显示任何结果。我已经在开源库代码中看到了这一点:

Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;

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


4
我想知道是否pipe equal operator向该问题或类似主题的任何其他文档添加内容不会帮助人们进行搜索。
DenysSéguret13年

10
@EJP你们在谈论这个文档。它清楚地告诉文档缺少有关此用法的文档。
wtsang02

36
除非您知道它被称为管道相等,否则不问某人就很难进行搜索。
2013年

确实,@ ataulm花了一些时间在谷歌上搜索vertical bar,最终提出了一个词条。
ruuter

Answers:


323

|=的读取方式与相同+=

notification.defaults |= Notification.DEFAULT_SOUND;

是相同的

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

|按位或运算符在哪里。

这里引用所有运算符。

之所以使用按位运算符,是因为经常使用这些常量使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

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

int myFlags = DEFAULT_SOUND | DEFAULT_VIBRATE; // same as 001 | 010, producing 011

所以

myFlags |= DEFAULT_LIGHTS;

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

对称地,我们使用&以下命令测试设置的标志:

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;

2
就像和j += 1;一样j = j + 1;
David Schwartz

1
@ARS:我想不出Java中的反例(也许jvolatile?),但是我会相信你的。
David Schwartz

6
@DavidSchwartz看到这个
arshajii

2
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;-您可以在Java中将它翻译intboolean吗?那在C语言中是有效的,但是我认为在Java语言中,它必须写为boolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
BlueRaja-Danny Pflughoeft13年

1
@DavidSchwartz哇,与+=我的比较终于使我理解了窍门。谢谢!
C4d

39

您已经有足够的答案来回答您的问题。但是也许我的答案可以帮助您更多地了解|=二进制运算符的种类。

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

----------------------------------------------------------------------------------------
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  
----------------------------------------------------------------------------------------

注意所有运算符都是二进制运算符。

请注意:( 对于以下几点,我想补充一下答案)

  • >>>是Java中的按位运算符,称为无符号移位
    >>>=不是Java中的运算符。 >>> =运算符

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

  • 另外, !称为逻辑NOT运算符,但!=检查两个操作数的值是否相等,如果值不相等,则条件为true。例如(A != B) is true。其中作为A=!B手段,如果BtrueA成为false(并且如果BfalseA成为true)。

旁注:|不是管道,而是管道的OR,管道是shell术语将一个过程转移到下一个过程。


9
我给人的印象是“管道”是字符的名称,这是外壳术语的来源。但是,从Wikipedia来看,它实际上称为“竖线”,而“管道”特定于Shell命令。只是想说谢谢您添加便条!
Caleb Brinkman 2014年

18

我一直在寻找|=Groovy中的功能的答案,尽管上面的答案是正确的,但它们并没有帮助我理解我正在查看的特定代码段。

特别是,当将其应用于布尔变量“ | =”时,它将在第一次遇到右侧的真实表达式时将其设置为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 

输出:

false
false
true
true

编辑:为什么这有用?

考虑一种情况,您想知道在各种对象上是否有任何更改,如果有更改,请通知其中的某些更改。因此,您将设置一个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

10
是的,在Java中也是如此。但值得注意的是,这样的OR操作y|=expr不短路(不像y = y || expr),这意味着expr总评估。这不是对我来说显然是第一次:)所以这是重构是更换前需要注意的重要y|=expry=y||x不是语义上等同的情况下,expr实际上有副作用。
NIA

1
而且,考虑到这一点, 你的情况hasChanges这将可能是更好的偏爱y=y||x从短期挑错推荐打印形式的好处,因为当你发现任何变化实际上并没有需要做susequent的diff,因为你已经知道答案。(在现实生活中,当被比较的对象比较复杂并且diff将它们放入对象的速度不太快时,这尤其重要)
NIA

@NIA感谢您的投票。是的,我同意您关于短路的观点。
dbrin

2
@FranklinYu当然不是实现细节。在您提到的地方,没有专门提到非短路问题,这仅仅是因为它不是特殊特性,它是大多数操作员的默认行为和正常行为。特殊性实际上是短circutiness ||&&,并在相应部分15.2315.24规范这一事实清楚地宣布,从这个差异|&强调。
NIA

2
@FranklinYu所以我觉得没有必要说一下这再次跌破节中引用你(15.26.2“复方赋值运算符”) 仅仅因为复合式分配只是总是非短路(有没有||=&&=运营商这将违反规则并需要特别提及)。
NIA

13

这是一个简化:

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

并且|是按位或。



3

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

y= y || expr; // expr is NOT evaluated if y==true

要么

y = expr ? true : y;  // expr is always evaluated.

4
不是很完整:您仍然可以使用booleansy |= expr并且它的结果y与变体相同,但要注意的是它不是short-curtuit,这意味着即使在y==true
NIA
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.