2014-12-10 13 views
35

c'è un modo per annullare "se let" in swift? Questo sembra sciocco a me:If not let - in Swift

if let type = json.type { 

    } else { 
     XCTFail("There is no type in the root element") 
    } 

non posso usare XCTAssertNotNil, perché json.type è un enum.

enum JSONDataTypes { 
    case Object 
    case Array 
    case Number 
    case String 
} 

Grazie mille

EDIT: si tratta di un:

var type: JSONDataTypes? = nil 
+1

È 'json.type' un semplice' JSONDataTypes', o è un 'JSONDataTypes?' (Opzionale)? –

+0

oh scusa: tipo var: JSONDataTypes? = nil –

risposta

33

Swift 2.0 (Xcode 7) e poi avere la nuova dichiarazione guard, che funziona come un "se non lo è" - puoi vincolare condizionatamente una variabile nel resto dell'en ambito di chiusura, mantenendo il "buon percorso" nel codice il meno rientrato.

guard let type = json.type else { 
    XCTFail("There is no type in the root element") 
} 
// do something with `type` here 

La cattura di questo è che la clausola else di un guard deve uscire da quella portata (perché altrimenti ci si cade in codice dopo tale clausola, dove le variabili custoditi, come type sopra, sono legato). Quindi deve finire con qualcosa come return, break, continue o una funzione che è nota al compilatore di non tornare mai (cioè annotata @noreturn, come abort() ... Non ricordo se questa include XCTFail, ma dovrebbe (file a bug if it's not).

per i dettagli, consultare Early Exit in La Swift Programming Language.


per quanto riguarda la roba veramente vecchio ... non c'è forma negata di se-let in 1.x. Swift Ma dal momento che stai lavorando con XCTest in ogni caso, puoi solo ma ke testare la parte opzionale di un'espressione asserzione:

XCTAssert(json.type != nil, "There is no type in the root element") 
+0

Grazie mille per questa spiegazione. Mi aiuta molto –

+0

Non c'è letteralmente "if not let" in Swift 2, ma la nuova istruzione 'guard' è praticamente ciò che stai cercando. Risposta aggiornata – rickster

+5

'guard let else {}' non è l'equivalente di 'if not let {}' dato che nell'ambito di 'guard' deve sempre chiamare' return' o 'break'. Non possono essere lasciati sfuggire: "il corpo 'di guardia' potrebbe non cadere, considerare l'uso di 'return' o 'break' per uscire dall'oscilloscopio. – richardjsimkins

18

Ecco come si fa:

if json.type == nil { 
    // fail 
} 
+1

Ciò non assegna json.type al tipo anche se –

+0

Naturalmente, poiché 'type' non è un optional e quindi non può contenere un valore nullo. La tua risposta non assegna nulla da digitare neanche. È impossibile. –

+3

@ChoppinBroccoli La domanda iniziale implica che a Peter Shaw non interessa il tipo effettivo. Sta scrivendo un caso di test che fallisce se 'json.type' è nullo e vuole farlo in modo più succinto. –

2

Un'altra alternativa ho usato un paio di volte:

switch json.type 
{ 
    case .None: // ... 
    case .Some(.Object): // ... 
    case .Some(.Array): // ... 
    case .Some(.Number): // ... 
    case .Some(.String): // ... 
} 

Poiché la ? è in realtà Optional<T> che è un'enumerazione di per sé, come definito :

enum Optional<T> : Reflectable, NilLiteralConvertible 
{ 
    case None 
    case Some(T) 

    ... 
}