“|=”是啥意思? (管道等号运算符)

Posted

技术标签:

【中文标题】“|=”是啥意思? (管道等号运算符)【英文标题】:What does "|=" mean? (pipe equal operator)“|=”是什么意思? (管道等号运算符) 【发布时间】:2012-12-27 01:21:40 【问题描述】:

我尝试使用 Google 搜索和 *** 进行搜索,但没有显示任何结果。我在开源库代码中看到了这一点:

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

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

【问题讨论】:

我想知道在这个问题中添加类似pipe equal operator 的内容或任何其他关于该主题的文档是否对人们搜索没有帮助。 @EJP 你们在谈论这个docs。它清楚地告诉文档缺少关于此使用的文档。 除非你知道它被称为管道相等,否则不问别人真的很难搜索。 @ataulm 确实,花了一些时间在谷歌上搜索想出一个术语 vertical bar 最终把我带到这里。 What does the |= operator do in Java?的可能重复 【参考方案1】:

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

notification.defaults |= Notification.DEFAULT_SOUND;

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

其中| 是按位或运算符。

所有运算符都引用here。

使用按位运算符,因为通常情况下,这些常量使 int 能够携带标志。

如果您 look 使用这些常量,您会发现它们是 2 的幂:

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;

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

对称地,我们测试一个标志是使用&amp; 设置的:

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

【讨论】:

就像j += 1;j = j + 1;一样。 @A.R.S.:我想不出Java中的反例(也许jvolatile?),但我会相信你的话。 @DavidSchwartz 见this boolean hasVibrate = DEFAULT_VIBRATE &amp; myFlags; - 你能像在Java中那样从int翻译成boolean吗?这在 C 中是有效的,但我认为在 Java 中它必须写为 boolean hasVibrate = ((DEFAULT_VIBRATE &amp; myFlags) == DEFAULT_VIBRATE); @DavidSchwartz 哇,与+= 的比较终于让我理解了它。谢谢!【参考方案2】:

这是一个缩写:

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

| 是按位或。

【讨论】:

【参考方案3】:

| 是bitwise-or 运算符,它的应用类似于+=

【讨论】:

【参考方案4】:

您的问题已经得到了足够的答案。但我的回答可能会帮助您更多地了解|= 类型的二元运算符。

我正在为bitwise operators写表: 以下是有效的:

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

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

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

&gt;&gt;&gt; 是 Java 中的按位运算符,称为 无符号移位&gt;&gt;&gt;= 不是 Java 中的运算符。 >>>= operator

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

另外,! 称为逻辑非运算符,但 != 检查两个操作数的值是否相等,如果值不相等则条件为真。例如(A != B) is true。其中A=!B 表示如果Btrue,则A 变为false(如果Bfalse,则A 变为true)。

旁注:| 不称为管道,而是称为 OR,管道是外壳术语,将一个进程转移到下一个进程..

【讨论】:

我的印象是“管道”是字符的名称,这就是 shell 术语的来源。但是,查看 Wikipedia,它实际上被称为“垂直条”,而“管道”特定于 shell 命令。只是想说感谢您添加该旁注!【参考方案5】:

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

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

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

【讨论】:

不太完整:您仍然可以将y |= expr 与布尔值一起使用,它在y 上给出的结果与您的变体相同,重要的是它不是简短的,这意味着 expr 总是被评估,即使是 y==true 简化版:y = expr || y; // expr is always evaluated.【参考方案6】:

我正在寻找关于 |= 在 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

【讨论】:

是的,Java 也是如此。但值得注意的是,这种 OR 操作 y|=exprnot short-circuit(与 y = y || expr 不同),这意味着 expr 总是被评估。这对我来说第一次并不明显 :) 所以在重构之前需要注意替换 y|=expry=y||x 在语义上不等效,以防 expr 实际上有副作用。 并且,考虑到这一点,在你的情况下使用hasChanges可能更喜欢y=y||x 形式以从中受益短路,因为当您发现任何更改时,实际上不需要进行后续差异,因为您已经知道答案。 (在现实生活中特别重要的是,当比较对象很复杂并且diff他们不是很快) @NIA 感谢您的支持。是的,我同意你关于短路的观点。 @FranklinYu 当然不是实现细节。在您引用的地方没有特别提到非短路只是因为它不是特殊性 - 它是大多数操作员的默认和正常行为。特殊性实际上是||&amp;&amp; 的短路,并且在规范的相应部分15.23 和15.24 中明确声明了这一事实,并强调了与|&amp; 的区别。 @FranklinYu 所以我认为没有必要在下面你引用 (15.26.2 "复合赋值运算符") 的部分中再次说明这一点,因为复合赋值是只是总是非短路(没有||=&amp;&amp;= 运算符会违反规则并需要特别提及)。

以上是关于“|=”是啥意思? (管道等号运算符)的主要内容,如果未能解决你的问题,请参考以下文章

PHP 中的 !== 比较运算符是啥意思?

在同一行上有多个等号是啥意思? [复制]

Scala Koans 中的 ===(三等号)运算符是啥?

C语言中num/=10是啥意思

C语言中的冒号(:)是啥意思?

c语言中num是啥意思