2011-07-12 12 views
14

Sto esaminando le differenze inviate a un progetto da un altro sviluppatore e hanno un sacco di codice che fa !!<some BOOL value>. In realtà, questo sembra essere il loro modello standard per l'implementazione di getter e setter booleani. Hanno implementato il loro codice come:Objective-C - È !! BOOL Beneficio

- (BOOL) hasId { 
    return !!hasId_; 
} 
- (void) setHasId:(BOOL) value { 
    hasId_ = !!value; 
} 

Non ho mai visto questo schema, prima, e mi chiedo se non v'è alcun beneficio in usarlo. La doppia negazione sta facendo qualcosa di utile?

+0

l'unica volta che ho visto che era per una classe che non ha un modo semplice per eseguire il cast, quindi non potevano fare 'if (myInstance)', ma ha sovraccaricato l'operatore unario '!' , così avrebbero fatto 'if (!! myInstance)'. Ma nel tuo caso, non ne ho idea. – filipe

risposta

13

L'operatore booleano doppia fa solo in modo che il valore restituito è un 1 o uno 0. Questo è tutto:)

+5

... che impedisce il codice come 'obj.hasId = 42; se (obj.hasId == YES) 'dal non riuscire la condizione. Tecnicamente 'YES' è (attualmente) mappato a 1 quindi i valori interi sono diversi. Concettualmente, però, sia 42 che 'YES' rappresentano un vero valore booleano. La doppia negazione collassa quella 42-assegnazione a un incarico 'YES'. –

+0

Grazie, ho pensato che fosse probabilmente qualcosa del genere. Ma è utile farlo in questo modo/sono evitati potenziali errori?Come forse questo impedisce un errore imprevisto quando si fa un confronto in forma di 'if (obj.hasId == SI)'? Comunque non è un tale confronto in stile povero comunque? Edit: Nevermind, Bavarious mi ha battuto su di esso. – aroth

+0

Vero, ma la sua realtà utile a volte, per la conversione a 1 o 0, come SQLite salva i campi booleani solo in 1 o 0. –

3

! è un operatore di negazione logica. Quindi, se setHasId: è stato passato, ad es., 0x2 allora la doppia negazione memorizzerebbe 0x1.

1

È equivalente a:

hasId_ = value ? 1 : 0; 

E 'utile in alcuni casi, perché se si esegue questa operazione:

BOOL x = y & MY_FLAG; 

Si potrebbe ottenere 0 se MY_FLAG è impostato, perché il risultato viene troncato a la dimensione di un BOOL (8 bit). Questo è inaspettato. Per gli stessi motivi, a volte le persone preferiscono che BOOL sia 0 o 1 (quindi le operazioni bit funzionano come previsto). Di solito non è necessario.

Nelle lingue con un tipo integrato bool come C (a partire da C99) e C++, la conversione di un numero intero in bool viene eseguita automaticamente.

0

ha più senso in alcuni altri casi, per esempio in cui si sta da restituire BOOL ma non si vuole porre if economico.

- (BOOL)isMyVarSet 
{ 
    return !!myVar; 
} 

In questo caso non posso tornare myVar perché è non è un BOOL (questo è un esempio molto elaborato: non riesco a ricavarne uno decente dai miei progetti).

0

Ho usato questo prima e credo:

if (!!myVar)

è equivalente a:

if (myVar != nil)

In sostanza, lo uso per verificare il valore di qualcosa.

Ammetto che ... probabilmente non è la migliore pratica o il modo più capito per raggiungere questo obiettivo.

+0

La differenza è: è abbastanza ovvio, mentre (!! myVar) si ferma nelle tracce, si deve riflettere ciò che fa, e poi si deve pensare ancora di più per (myVar = nil!) capire se chi l'ha scritto lo ha effettivamente significato. Meglio esprimere chiaramente ciò che intendi. – gnasher729

+0

Completamente d'accordo! La mia risposta è 3 anni, e io assolutamente non avrebbe scritto !! var in qualsiasi nuovo codice di oggi! – mbm29414