Cosa significa "| ="? (operatore uguale al tubo)


249

Ho provato a cercare usando Ricerca Google e Stack Overflow, ma non ho mostrato alcun risultato. Ho visto questo nel codice della libreria opensource:

Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;

Cosa significa "| =" ( pipe equal operator)?


4
Mi chiedo se aggiungere qualcosa di simile pipe equal operatora questa domanda o qualsiasi altra documentazione sull'argomento non aiuterebbe le persone a cercare.
Denys Séguret,

10
@EJP ragazzi state parlando di questi documenti . Indica chiaramente che i documenti mancano di documentazione sull'uso di questo.
wtsang02

36
A meno che tu non sapessi che si chiamava pipe uguale, è davvero difficile cercare senza chiedere a qualcuno.
ataulm,

@ataulm in effetti, ho passato un po 'di tempo a cercare su google un termine vertical barche alla fine mi ha portato qui.
ruuter,

Risposte:


323

|=legge allo stesso modo di +=.

notification.defaults |= Notification.DEFAULT_SOUND;

equivale a

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

dov'è |l'operatore OR bit-saggio.

Tutti gli operatori sono indicati qui .

Un operatore bit-saggio viene utilizzato perché, come è frequente, quelle costanti consentono a un int di trasportare flag.

Se guardi quelle costanti, vedrai che hanno poteri di due:

public static final int DEFAULT_SOUND = 1;
public static final int DEFAULT_VIBRATE = 2; // is the same than 1<<1 or 10 in binary
public static final int DEFAULT_LIGHTS = 4; // is the same than 1<<2 or 100 in binary

Quindi puoi usare bit-saggio O per aggiungere flag

int myFlags = DEFAULT_SOUND | DEFAULT_VIBRATE; // same as 001 | 010, producing 011

così

myFlags |= DEFAULT_LIGHTS;

significa semplicemente che aggiungiamo una bandiera.

E simmetricamente, testiamo che un flag sia impostato usando &:

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;

2
Proprio come j += 1;è lo stesso di j = j + 1;.
David Schwartz,

1
@ARS: Non riesco a pensare a un contro-esempio in Java (forse se lo jè volatile?), Ma prenderò la tua parola per questo.
David Schwartz,

6
@DavidSchwartz Vedi questo
arshajii,

2
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;- si può tradurre da inta booleanquel modo in Java? Sarebbe valido in C, ma pensavo che in Java dovesse essere scritto comeboolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
BlueRaja - Danny Pflughoeft

1
@DavidSchwartz Wow, quel confronto con +=finalmente mi ha aiutato a comprenderlo. Grazie!
C4d,

39

Hai già ricevuto una risposta sufficiente per la tua domanda. Ma potrebbe essere la mia risposta aiutarti di più sul |=tipo di operatori binari.

Sto scrivendo una tabella per operatori bit a bit :
sono validi i seguenti:

----------------------------------------------------------------------------------------
Operator   Description                                   Example
----------------------------------------------------------------------------------------
|=        bitwise inclusive OR and assignment operator   C |= 2 is same as C = C | 2
^=        bitwise exclusive OR and assignment operator   C ^= 2 is same as C = C ^ 2
&=        Bitwise AND assignment operator                C &= 2 is same as C = C & 2
<<=       Left shift AND assignment operator             C <<= 2 is same as C = C << 2
>>=       Right shift AND assignment operator            C >>= 2 is same as C = C >> 2  
----------------------------------------------------------------------------------------

si noti che tutti gli operatori sono operatori binari.

Nota anche : (per i punti seguenti ho voluto aggiungere la mia risposta)

  • >>>è un operatore bit a bit in Java che si chiama spostamento senza segno
    ma >>>=non un operatore in Java. >>> = operatore

  • ~sono bit di complemento bit a bit 0 to 1 and 1 to 0(operatore unario) ma ~=non un operatore.

  • Inoltre, !chiamato Logical NOT Operator, ma !=controlla se il valore di due operandi è uguale o no, se i valori non sono uguali la condizione diventa vera. es (A != B) is true. dove come A=!Bsignifica se Bè truepoi Adiventato false(e se Bè falsepoi Adiventato true).

nota a margine: |non si chiama pipe, invece si chiama OR, pipe è shell terminology transfer da un processo al successivo.


9
Avevo l'impressione che "pipe" fosse il nome del personaggio, da cui deriva il termine shell. Ma, guardando Wikipedia, in realtà si chiama "barra verticale" e "pipe" è specifico per i comandi della shell. Volevo solo dire grazie per aver aggiunto quella nota a margine!
Caleb Brinkman,

18

Stavo cercando una risposta su cosa |=fa Groovy e sebbene le risposte sopra siano esatte, non mi hanno aiutato a capire un particolare codice che stavo guardando.

In particolare, quando applicato a una variabile booleana "| =" la imposterà su VERO la prima volta che incontra un'espressione veritiera sul lato destro e manterrà il suo valore VERO per tutte le chiamate successive = =. Come un chiavistello.

Ecco un esempio semplificato di questo:

groovy> boolean result  
groovy> //------------ 
groovy> println result           //<-- False by default
groovy> println result |= false 
groovy> println result |= true   //<-- set to True and latched on to it
groovy> println result |= false 

Produzione:

false
false
true
true

Modifica : perché è utile?

Considera una situazione in cui vuoi sapere se qualcosa è cambiato su una varietà di oggetti e in tal caso avvisare qualcuno delle modifiche. Quindi, dovresti impostare un valore hasChangesbooleano e impostarlo su |= diff (a,b)e quindi |= dif(b,c)ecc. Ecco un breve esempio:

groovy> boolean hasChanges, a, b, c, d 
groovy> diff = {x,y -> x!=y}  
groovy> hasChanges |= diff(a,b) 
groovy> hasChanges |= diff(b,c) 
groovy> hasChanges |= diff(true,false) 
groovy> hasChanges |= diff(c,d) 
groovy> hasChanges 

Result: true

10
Sì, lo stesso vale per Java. Ma vale la pena notare che tale operazione OR nony|=expr è in cortocircuito (a differenza y = y || expr), nel senso che viene exprsempre valutata. Questo non è stato ovvio per me per la prima volta :) Quindi è importante notare prima di refactoring che la sostituzione y|=exprnony=y||x è semanticamente equivalente nel caso in cui exprabbia effettivamente effetti collaterali.
NIA,

1
E, avendo questo in mente, nel tuo caso con hasChangessarebbe probabilmente essere meglio preferire y=y||xforma di beneficiare a breve ciruit, perché quando hai trovato alcun cambiamento non è effettivamente bisogno di fare diff acquisite successivamente perché sai già la risposta. (Particolarmente importante nella situazione di vita reale quando gli oggetti a confronto sono complicati e diffnon è abbastanza veloce
inginocchiarli

@NIA Grazie per il voto positivo. Sì, sono d'accordo con il tuo punto sul corto circuito.
dbrin,

2
@FranklinYu ovviamente non dettagli di implementazione. La non-cortocircuito non è specificatamente menzionata nel luogo a cui si fa riferimento solo perché non è la peculiarità: è il comportamento predefinito e normale per la maggior parte degli operatori. La particolarità è in realtà la cortocircuito di ||e &&, e nelle corrispondenti sezioni 15.23 e 15.24 delle specifiche, questo fatto è chiaramente dichiarato e questa differenza da |e &viene enfatizzata.
NIA,

2
@FranklinYu Quindi penso che non ci fosse bisogno di dire qualcosa di nuovo qui sotto nella sezione a cui hai fatto riferimento (15.26.2 "Operatori di assegnazione di compund") solo perché le assegnazioni di compond sono semplicemente non in cortocircuito (non ci sono ||=e &&=operatori che infrangere la regola e richiedere menzioni speciali).
NIA,

13

È un accorciamento per questo:

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

Ed |è un OR un po 'saggio.



3

Nota: || = non esiste. (logico o) È possibile utilizzare

y= y || expr; // expr is NOT evaluated if y==true

o

y = expr ? true : y;  // expr is always evaluated.

4
Non del tutto completo: puoi ancora usarlo y |= exprcon i booleani e dà lo stesso risultato delle ytue varianti con l'importante nota che non è a corto raggio , il che significa che expr viene sempre valutato, anche in caso diy==true
NIA
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.