存在非短路逻辑运算符的原因

boolean操作数一起使用时, &| 成为JLS第15.22.2节的 逻辑运算符。 不像&&|| 但是,这些不会短路; 他们总是评估双方。 我有一个愚蠢的问题:当我们有更高效的短路逻辑运算符( &&|| )时,为什么低效率的非短路逻辑运算符( &| )仍然存在? 我的意思是,与短路逻辑运算符相反,非短路逻辑运算符的实际用法是什么? 换句话说,通过使用非短路逻辑运算符总是评估双方的用法是什么?

更新回答

道歉,我错过了“逻辑”这个词,尽pipe它那里。 (我已经自由地强调了一下编辑。)

考虑一下你希望任何副作用总是发生的情况,而不pipe左侧expression式是否为true或者false 。 例如,对比:

 if (foo() & bar()) { // Only call this if both operations returned true } 

 if (foo() && bar()) { // Only call this if both operations returned true } 

假设foobar都具有我们希望发生的效果,而不pipefoo返回true还是false 。 在上面的第一个中,我知道 bar总是会被调用并起作用。 在后者当然, bar可能会或可能不会被召唤。 如果我们没有非短路版本,我们不得不使用临时variables:

 boolean fooResult, barResult; fooResult = foo(); barResult = bar(); if (fooResult && barResult) { // ... } 

你可能会争论(我可能会),你应该这样做,因为if (foo() & bar())太容易误读,但是我们有一个非短路版本的实用理由。

原始答案

你如何build议& (或| )做一个短路操作员? 用&&|| ,这是有道理的,因为你在处理布尔条件:它们可以是真或假,没有灰色阴影。 但是&| 处理位,而不是布尔值。 结果是一个数字。 我的意思是,如果左边是0 ,我猜&不能评价右边,并且类似于| 如果左手边是无论什么types,都不能评价它,但是我没有看到多less点使每个运算符的一个边缘情况有意义(与254个或更多的其他情况相比) )。

在某些情况下,布尔expression式的组件涉及您想要在所有情况下执行的操作。 考虑下面的例子检查密码的有效性:

 while ( !password.isValid() & (attempts++ < MAX_ATTEMPTS) ) { // re-prompt } 

如果第二个条件由于短路而未被评估,则attempts永远不会增加。 这样可以提高程序员的灵活性。

您可以在逻辑expression式中有一些副作用,例如您可以同时进行检查。 如果只评估一个部分,这可能会工作错误。

现在不记得好的例子,但是请记住我有时需要“非短路”的操作员。

嗯….下面是错误的例子,这将不工作没有“非短路”或:

 if( (object1=getInstance1()).getNumber() == 1 || (object2=getInstance2()).getNumber() == 2 ) { // do something which requires bot object1 and object2 assigned } 

我的情况(C ++):

 void setFields(Parameters bundle) { if (setIfDifferent(&field1, bundle.value1) | setIfDifferent(&field2, bundle.value2) | setIfDifferent(&field3, bundle.value3)) { storeState(); } } 

如果setIfDifferent()不同,setIfDifferent()会将对象的字段设置为新值,在这种情况下,它会返回true; 或者在字段和新值相同的情况下返回false。 所以,我们想要设置所有的字段,如果它们中的任何一个改变了,那么我们要存储新的对象的状态。

在我的情况下,我有两个方法比较两个不同但相关的对象(Object2是Object1的一个属性),以查看是否有任何更改。 更新需要发生,如果更新,但都需要评估,以便对象将被修改,如果两者都被更改。 因此,需要单个pipe道“或”比较。

EX:

 if (compare(object1, currentObject1) | comparison(object2, currentObject2)) { updateObject1(object1); } 

从技术上讲,&和| 是不合逻辑的,它们是位运算符,当与布尔运算符关联时变成逻辑运算符。

有时候你想在你的逻辑expression式中包含赋值expression式。

说:

 if(a = (checkForSomeCondition()) | b = checkForAnotherCondition()) { //now do something here with a and b that has been cached } 

如果我使用||,我不能执行上面的检查,并且不得不将分配分解成单独的语句。 在应用程序开发过程中,我从来没有遇到类似这样的场景,但是在编写algorithm的时候遇到了这个问题。

当然,你可以在逻辑expression式上使用一元运算符,或者通过引用将谓词传递给谓词,但是这些似乎不如上述那样普遍。