Java / Scala中的非短路逻辑(布尔)运算符有很好的用途吗?

Are there good uses for non-short-circuiting logical (boolean) operators in Java/Scala?

我最近发现Java(和斯卡拉)包括非短路逻辑运算符EDCOX1,0,EDCOX1,1,EDCX1,2。我以前认为这些只作为位运算符工作。虽然^可能有一个论点,但我想不出使用非短路逻辑运算符的非常好的理由——尽管可以,我可以设计一个例子。

这些运算符有用吗?它们似乎更容易引起难以捕捉的虫子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
scala> def foo = {
     |   println("foo")
     |   true
     | }
foo: Boolean

scala> def bar = {
     |   println("bar")
     |   true
     | }
bar: Boolean

scala> foo || bar
foo
res5: Boolean = true

scala> foo | bar
foo
bar
res6: Boolean = true


如果右侧是一个有副作用的函数,不管您想执行什么(例如日志记录),它们都很有用。但是,我建议这是一种代码味道,对下一个家伙来说肯定是没有意义的。


嗯,我知道它们对于优化C/C++代码非常有用,如果仔细使用的话。它可能也适用于Java。

除了实际的位操作之外,C语言的主要用途是消除管道阻塞。短路操作员需要进行分支操作。位运算符将计算两边,并消除预测失误的分支和导致的暂停的可能性。


使用非短路布尔运算符意味着操作数有副作用。如果它们没有副作用,那么程序员就可以使用短路版本而不改变功能。

在以函数样式编写的代码中(scala肯定鼓励但不要求),副作用表示正在发生一些不寻常的事情。不寻常的事情应该在代码中清楚地表示出来,而不是用像非短路布尔运算符这样微妙的东西。


如果你试图追踪某个问题的答案或输入,这取决于你的非短路布尔运算的两边。

例如,假设您有:

1
2
3
if(methodA() & methodB()){
    //some code
}

在methodb()方法中,一些基本的代码正在运行。如果这是一个短路代码(&;&;)并且methodA()为false,那么methodB()将永远不会运行。

至少这是我能想到的用途之一。