2012-03-02 14 views
10

Recentemente ho scoperto che Java (e Scala) includono operatori logici senza cortocircuito &, | e ^. In precedenza ho pensato che funzionassero solo come operatori bit a bit. Mentre forse c'è un argomento per ^, non riesco a pensare a dei buoni motivi per usare operatori logici senza cortocircuiti - sebbene sia sicuro, posso inventare un esempio.Esistono buoni usi per operatori logici (booleani) non a corto circuito in Java/Scala?

Questi operatori sono utili? Sembrano più propensi a causare bug difficili da catturare.

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

No, gli operatori bit a bit devono essere utilizzati solo per operazioni bit a bit, IMHO :) –

+1

Le uniche risposte possibili a questa domanda sono esempi specifici di "operatori non cortocircuitanti sono utili quando non si desidera cortocircuiti". Quindi la vera domanda è "quando non vuoi cortocircuiti"? –

risposta

14

Sono utili se il lato destro è una funzione con effetti collaterali che si desidera eseguire indipendentemente (ad esempio la registrazione). Tuttavia, suggerirei che è un po 'un odore di codice e sarà certamente non intuitivo per il prossimo ragazzo.

+1

Totalmente d'accordo, questo non dovrebbe essere fatto nel codice reale. –

+0

Come ho detto, posso fare un esempio forzato ;-) – schmmd

8

Hmm. So che possono essere incredibilmente utili per l'ottimizzazione del codice C/C++ se usati con attenzione. Potrebbe valere anche per Java.

L'uso principale in C, diverso dalle operazioni bit effettive, consiste nel rimuovere uno stallo della pipeline. Gli operatori di cortocircuito richiedono un'operazione di diramazione. L'operatore bit a bit calcolerà entrambi i lati e rimuoverà la possibilità di un ramo errato e lo stallo risultante.

+0

Immagino che dovresti bilanciare il costo dello stallo con il costo dell'esecuzione del codice che altrimenti non avrebbe bisogno di essere eseguito/influenzare l'esito del programma – dty

+0

@dty: Sì, assolutamente. Notare "se usato con attenzione". :-) –

+5

Durante la stesura di "com.google.common.math" di Guava, quando la seconda condizione era particolarmente veloce, i miei benchmark a volte indicavano che gli operatori non a corto circuito erano più veloci degli operatori a corto circuito per questo motivo. (Ciò detto, non avrei apportato questo cambiamento se non avessi benchmark dettagliati e molto solidi). –

0

Se si sta tentando di tracciare risposte o input per qualcosa, e ciò dipende da entrambi i lati della corsa booleana non a corto circuito.

Per fare un esempio, supponiamo di avere:

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

E all'interno del metodo MethodB() un codice essenziale è in esecuzione. Se quello era un codice di cortocircuito (& &) e methodA() era falso, methodB() non sarebbe mai stato eseguito.

Questo è uno degli usi a cui riesco a pensare, almeno.

2

L'utilizzo di operatori booleani non a corto circuito implica che gli operandi abbiano effetti collaterali. Se non avessero effetti collaterali, il programmatore avrebbe potuto utilizzare le versioni di cortocircuito senza modifiche di funzionalità.

Nel codice scritto in uno stile funzionale (che Scala sicuramente incoraggia ma non richiede), gli effetti collaterali indicano che qualcosa di insolito sta succedendo. Le cose insolite dovrebbero essere chiaramente indicate nel codice, piuttosto che con qualcosa di così sottile come un operatore booleano non a corto circuito.

Problemi correlati