2015-10-01 13 views
6

Quindi, in Objective-C quando si utilizza booleani è possibile, e incoraggiato, a scrivere codice usando diverso da zero il valore di una variabile, in quanto il suo valore booleano, che significa che è possibile scrivere codice come questo:Swift booleano controllo

if (someBool) { 
    // Stuff 
} 

Inoltre, ci sono ragioni per le quali il codice come il seguente è sconsigliato:

if (someBool == YES) { 
    // Might run into problems here 
} 

I motivi per cui il controllo di una booleana contro un altro booleano sono meglio spiegato here, ma per breve tempo il problema è solo che quando si sta confrontando l'uguaglianza di YES o NO direttamente, si sta effettivamente confrontando con 1 e 0, rispettivamente. Poiché Objective-C consente di utilizzare valori diversi da zero come valore di verità, è possibile finire per confrontare qualcosa che dovrebbe essere considerato vero contro YES e avere l'espressione risolta in NO, ad es.

int trueNumber = 2; 
if (trueNumber == YES) { 
    // Doesn't run because trueNumber != 1 
} 

È ancora un problema in Swift? Problemi di stile del codice a parte, se vedo qualcosa di simile al seguente

var someBool = true 
if someBool == true { 
    // stuff 
} 

è che sta per essere un problema, o non importa davvero? Questi confronti in stile C stanno ancora avvenendo sotto il cofano, o c'è qualcosa di incorporato nel Swift BooleanType che impedisce questi problemi?

risposta

2

La struttura if <something> {} a Swift richiede l'<something> di conformarsi al protocollo BooleanType che è definito in questo modo:

public protocol BooleanType { 
    /// The value of `self`, expressed as a `Bool`. 
    public var boolValue: Bool { get } 
} 

Se il tipo non è conforme a questo protocollo, viene generato un errore in fase di compilazione n. Se si cerca questo protocollo nella libreria standard, si scopre che l'unico tipo conforme a questo protocollo è lo stesso Bool. Bool è un tipo che può essere true o false. Non pensarlo come il numero 1 o 0, ma piuttosto come On/Off Giusto/Sbagliato.

Ora, questo protocollo può essere conformato a da qualsiasi tipo nominale che si desidera, ad esempio:

extension Int : BooleanType { 
    public var boolValue : Bool { 
     return self > 0 
    } 
} 

Ora, se si esegue questa operazione (non si dovrebbe onestamente), che si sta definendo da soli ciò che "True "e" False "significa. Ora si sarebbe in grado di utilizzarlo in questo modo (ancora una volta, non farlo):

if 0 { 
    ... 
} 
+0

Ok, quindi il motivo per cui il codice che era un problema in Objective-C non è un problema è semplicemente a causa del rigoroso controllo dei tipi in Swift? Sembra che per essere usato nei controlli booleani in Swift, un tipo deve sostanzialmente restituire un 'Bool' tipicamente scritto (come mostrato sopra), che evita il problema che C e Objective-C hanno avuto con il' typedef ha firmato il char'. È così semplice? – Ziewvater

+0

@Ziewvater Sì, corretto – Kametrixom

2

Swift ha tipo Bool. Questo è diverso dal BOOL dell'obiettivo-c che non è di tipo reale. In realtà è un char non firmato typedef. Quando swift si aspetta Bool devi dargli Bool altrimenti è un errore di compilazione. Il seguente codice non viene compilato perché di controllo non è bool

let check = 2 
if check { 
} 

Ma questo funziona perché == ritorna Bool

let check = 2 
if check == 2 { 
} 
+0

realtà 'Bool' è il suo proprio tipo di Swift e * non * un tipo alias" char non firmato "(che sarebbe" CUnsignedChar "in Swift). –

+0

Scusa, intendo Objective-C non swift – mustafa

+0

Bene, è più complicato in Objective-C, confronta http://stackoverflow.com/questions/31267325/bool-with-64-bit-on-ios. –

0

Per capire lo stile objC, è necessario tornare a C.In C, questa dichiarazione:

if (something) { 
    // Do something 
} 

valuterà a false se something è null o 0. Tutto il resto restituiscono true. Il problema è che C non ha un tipo booleano. Objective-C ha aggiunto YES e NO che è fondamentalmente 1 e 0. Quindi:

if (aBoolValue == YES) { } // Work as expected 
if (anIntValue == YES) { } // False unless anIntValue == 1 

La raccomandazione "scoraggiati" è stato quello di allinearsi con il comportamento in C. Swift non ha tali requisiti di compatibilità all'indietro. Non è possibile scrivere questi:

Invece, l'espressione deve restituire un valore booleano:

if anIntValue != 0 { } // Ok 
if anObject != nil { } // Ok