Существуют ли хорошие возможности для логических (булевых) операторов с коротким замыканием в 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() никогда не запускался.
Это одно из видов использования, о котором я могу думать, по крайней мере.