“|=”是啥意思? (管道等号运算符)
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;
只是意味着我们添加了一个标志。
对称地,我们测试一个标志是使用&
设置的:
boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;
【讨论】:
就像j += 1;
和j = j + 1;
一样。
@A.R.S.:我想不出Java中的反例(也许j
是volatile
?),但我会相信你的话。
@DavidSchwartz 见this
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;
- 你能像在Java中那样从int
翻译成boolean
吗?这在 C 中是有效的,但我认为在 Java 中它必须写为 boolean hasVibrate = ((DEFAULT_VIBRATE & 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
----------------------------------------------------------------------------------------
注意所有运算符都是二元运算符。
另外注意: (对于以下几点我想添加我的答案)
>>>
是 Java 中的按位运算符,称为 无符号移位但 >>>= operator >>>=
不是 Java 中的运算符。
~
是按位补码,0 to 1 and 1 to 0
(一元运算符)但~=
不是运算符。
另外,!
称为逻辑非运算符,但 !=
检查两个操作数的值是否相等,如果值不相等则条件为真。例如(A != B) is true
。其中A=!B
表示如果B
是true
,则A
变为false
(如果B
是false
,则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|=expr
是 not short-circuit(与 y = y || expr
不同),这意味着 expr
总是被评估。这对我来说第一次并不明显 :) 所以在重构之前需要注意替换 y|=expr
↔ y=y||x
在语义上不等效,以防 expr
实际上有副作用。
并且,考虑到这一点,在你的情况下使用hasChanges
,可能更喜欢y=y||x
形式以从中受益短路,因为当您发现任何更改时,实际上不需要进行后续差异,因为您已经知道答案。 (在现实生活中特别重要的是,当比较对象很复杂并且diff
他们不是很快)
@NIA 感谢您的支持。是的,我同意你关于短路的观点。
@FranklinYu 当然不是实现细节。在您引用的地方没有特别提到非短路只是因为它不是特殊性 - 它是大多数操作员的默认和正常行为。特殊性实际上是||
和&&
的短路,并且在规范的相应部分15.23 和15.24 中明确声明了这一事实,并强调了与|
和&
的区别。
@FranklinYu 所以我认为没有必要在下面你引用 (15.26.2 "复合赋值运算符") 的部分中再次说明这一点,因为复合赋值是只是总是非短路(没有||=
和&&=
运算符会违反规则并需要特别提及)。以上是关于“|=”是啥意思? (管道等号运算符)的主要内容,如果未能解决你的问题,请参考以下文章