Существуют ли хорошие возможности для логических (булевых) операторов с коротким замыканием в Java/Scala?

Недавно я обнаружил, что Java (и Scala) включают в себя логические операторы с коротким замыканием &, | и ^. Ранее я думал, что они работают только как побитовые операторы. Хотя, возможно, есть аргумент для ^, я не могу придумать очень веские причины для использования короткозамкнутых логических операторов - хотя, конечно, я могу придумать пример.

Являются ли эти операторы полезными? Вероятнее всего, они могут вызывать ошибки с жестким ловушкой.

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

Ответ 1

Они полезны, если правая сторона - это функция с побочными эффектами, которые вы хотите выполнить независимо (например, протоколирование). Однако я бы предположил, что это немного запах кода и, конечно же, будет неинтуитивным для следующего парня.

Ответ 2

Хм. Я знаю, что они могут быть невероятно полезны для оптимизации кода C/С++, если использовать его тщательно. Он также может применяться к Java.

Основное использование в C - кроме фактических операций с битами - это удаление конвейера. Операторам короткого замыкания требуется операция ветвления. Побитовый оператор будет вычислять обе стороны и удаляет вероятность ошибочной ветки и результирующего срыва.

Ответ 3

Использование булевых операторов без коротких замыканий означает, что операнды имеют побочные эффекты. Если у них не было побочных эффектов, программист мог использовать варианты короткого замыкания без изменения функциональности.

В коде, написанном в функциональном стиле (который Scala наверняка поощряет, но не требует), побочные эффекты являются признаком того, что происходит что-то необычное. Необычные вещи должны быть четко обозначены в коде, а не чем-то таким же тонким, как булевым оператором с коротким замыканием.

Ответ 4

Если вы пытаетесь отследить ответы или ввод для чего-то, и это зависит от обеих сторон вашего буфера с коротким замыканием.

В качестве примера скажем, что у вас есть:

if(methodA() & methodB()){
    //some code
}

И в методе methodB() выполняется некоторый важный код. Если это был код короткого замыкания (&) и методA() был ложным, метод B() никогда не запускался.

Это одно из видов использования, о котором я могу думать, по крайней мере.