Utilizzo di più let-as all'interno di un'istruzione if in Swift


144

Sto scartando due valori da un dizionario e prima di usarli devo lanciarli e testare il tipo giusto. Questo è quello che mi è venuto in mente:

var latitude : AnyObject! = imageDictionary["latitude"]
var longitude : AnyObject! = imageDictionary["longitude"]

if let latitudeDouble = latitude as? Double  {
   if let longitudeDouble = longitude as? Double {
       // do stuff here
   }
}

Ma vorrei mettere insieme le due se lasciamo le domande in una. In modo che sarebbe qualcosa del genere:

if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double {
    // do stuff here
}

Quella sintassi non funziona, quindi mi chiedevo se ci fosse un modo bellissimo per farlo.


1

Potrebbe esserci un modo per utilizzare un'istruzione switch per corrispondere ai tipi. Dai un'occhiata a Documenti :
lomokat,

1
possibile duplicato
dell'utilizzo

Risposte:


305

Aggiornamento per Swift 3:

In Swift 3 funzionerà quanto segue:

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double {
    // latitudeDouble and longitudeDouble are non-optional in here
}

Ricordati solo che se uno dei tentativi di bind opzionali fallisce, il codice all'interno del if-letblocco non verrà eseguito.

Nota: le clausole non devono essere tutte clausole 'let', puoi avere qualsiasi serie di controlli booleani separati da virgole.

Per esempio:

if let latitudeDouble = latitude as? Double, importantThing == true {
    // latitudeDouble is non-optional in here and importantThing is true
}

Swift 1.2:

Apple potrebbe aver letto la tua domanda, perché il tuo codice sperato si compila correttamente in Swift 1.2 (in beta oggi):

if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double {
    // do stuff here
}

Swift 1.1 e precedenti:

Ecco la buona notizia: puoi farlo totalmente. Un'istruzione switch su una tupla dei tuoi due valori può utilizzare la corrispondenza del modello per eseguire il cast di entrambi Doublecontemporaneamente:

var latitude: Any! = imageDictionary["latitude"]
var longitude: Any! = imageDictionary["longitude"]

switch (latitude, longitude) {
case let (lat as Double, long as Double):
    println("lat: \(lat), long: \(long)")
default:
    println("Couldn't understand latitude or longitude as Double")
}

Aggiornamento: questa versione del codice ora funziona correttamente.


funziona per me in 6.1.1, @AaronBratcher perché non per te?
Daniel Gomez Rico,

1
In Swift 1.2, è ora possibile fare questo in una sola riga: stackoverflow.com/a/28418847/1698576
smithclay

Nel tuo codice, hai 2 opzionali da scartare. Deve essere usato sempre così? Ho un codice confuso diverso. if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {...}. Anche il secondo let è facoltativo? Voglio dire, appnon è più un optional. giusto?
Miele,

1
È. appnon è più un optional, ma la sua windowproprietà è (il suo tipo è UIWindow?), quindi è quello che stai scartando.
Nate Cook,

7

Con Swift 3, è possibile utilizzare il concatenamento opzionale, l'istruzione switch o il modello opzionale per risolvere il problema.


1. Utilizzo if let(rilegatura opzionale / concatenamento opzionale)

Il linguaggio di programmazione Swift afferma il concatenamento opzionale:

È possibile concatenare più query insieme e l'intera catena ha esito negativo se un collegamento nella catena è nullo.

Pertanto, nel caso più semplice, è possibile utilizzare il modello seguente per utilizzare più query nell'operazione di concatenamento opzionale:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if let latitude = latitude as? Double, let longitude = longitude as? Double {
    print(latitude, longitude)
}

// prints: 2.0 10.0

2. Utilizzo di tuple e associazione di valori in un'istruzione switch

In alternativa a un semplice concatenamento opzionale, l'istruzione switch può offrire una soluzione a grana fine se utilizzata con tuple e associazione di valore:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude, longitude) {
case let (Optional.some(latitude as Double), Optional.some(longitude as Double)):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude, longitude) {
case let (latitude as Double, longitude as Double):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude as? Double, longitude as? Double) {
case let (.some(latitude), .some(longitude)):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude as? Double, longitude as? Double) {
case let (latitude?, longitude?):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0

3. Usare le tuple con if case(modello opzionale)

if case( modello facoltativo ) fornisce un modo conveniente per scartare i valori dell'enumerazione facoltativa. Puoi usarlo con le tuple per eseguire alcuni concatenamenti opzionali con più query:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (.some(latitude as Double), .some(longitude as Double)) = (latitude, longitude) {
    print(latitude, longitude)
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (latitude as Double, longitude as Double) = (latitude, longitude) {
    print(latitude, longitude)
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (.some(latitude), .some(longitude)) = (latitude as? Double, longitude as? Double) {
    print(latitude, longitude)
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (latitude?, longitude?) = (latitude as? Double, longitude as? Double) {
    print(latitude, longitude)
}

// prints: 2.0 10.0

5

Swift 3.0

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double {
    // do stuff here
}

4
Dovresti suggerire una modifica alla risposta accettata, non aggiungere un'altra risposta di qualità inferiore.
jervine10,
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.