2014-07-06 13 views
108

Rozpakowuję dwie wartości ze słownika i przed ich użyciem muszę je rzucić i przetestować pod kątem odpowiedniego typu. Oto, co wymyśliłem:Używanie wielu let-as wewnątrz instrukcji if w Swift

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 
    } 
} 

Ale chciałbym spakować dwa, jeśli niech zapytania w jednym. Tak, że to będzie coś takiego:

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

To składnia nie działa, więc zastanawiałem się, czy nie było to piękny sposób, aby to zrobić.

+1

możliwe duplikat [rozpakowaniu wielu ewentualne, jeśli instrukcja] (http://stackoverflow.com/questions/24548999/unwrapping-multiple-optionals-in-if-statement) – Jack

+0

Może istnieć sposób użycia instrukcji switch do wzorca mat ch typów. Spójrz na [Dokumenty] (https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/TypeCasting.html#//apple_ref/doc/uid/TP40014097-CH22-XID_448): – lomokat

+1

możliwy duplikat [Używanie "jeśli pozwól ..." z wieloma wyrażeń] (http://stackoverflow.com/questions/24118900/using-if-let-with-many-expressions) – rickster

Odpowiedz

215

Aktualizacja Swift 3:

Poniższe zadziała w Swift 3:

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

prostu należy pamiętać, że jeśli jedna z prób opcjonalnych wiązań nie, kod wewnątrz blok if-let nie zostanie wykonany.

Uwaga: w klauzulach nie wszystkie muszą być klauzulami "let", każda seria boolowskich czeków może być oddzielona przecinkami.

Na przykład:

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

Swift 1.2:

Apple może Przeczytałem to pytanie, ponieważ Twój kod oczekiwanych kompiluje poprawnie w Swift 1.2 (w wersji beta dzisiaj):

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

Swift 1.1 i wcześniejsze:

Oto dobra wiadomość - można całkowicie to zrobić. Instrukcja switch na krotki swoich dwóch wartości można użyć wzoru dopasowywania do oddania oboje do Double w tym samym czasie:

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") 
} 

Aktualizacja: Ta wersja kodu działa teraz poprawnie.

+0

To nie działa w Xcode 6.1.1 albo :( –

+0

działa dla mnie w 6.1.1, @AaronBratcher dlaczego nie do ciebie? – Caipivara

+0

Sprawdź http://swiftstub.com/569478972/ – Caipivara

4

Swift 3,0

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

Powinieneś zasugerować zmianę do zaakceptowanej odpowiedzi, nie dodawaj kolejnej odpowiedzi o niższej jakości. – jervine10

2

Z Swift 3, można użyć opcjonalnego łańcuchowym, switch lub opcjonalnej wzór w celu rozwiązania problemu.


1. Korzystanie if let (opcjonalnie wiązania/opcjonalnie łańcuchowym)

W Swift Programming Language stany o opcjonalnym łańcuchowych:

Wiele zapytań mogą być połączone w łańcuch, a cały łańcuch nie wdzięcznie jeśli link w łańcuchu jest zerowy.

Dlatego w najprostszym przypadku można użyć następującego wzoru do korzystania z wielu zapytań w opcjonalnej pracy łańcuchowym:

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. Korzystanie krotki i wiążące w instrukcji switch wartość

Jako alternatywę dla prostego opcjonalnego łączenia, switch statement może zaoferować drobnoziarniste rozwiązanie, gdy jest używane z krotkami i wiązaniem wartości:

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. Za pomocą krotki z if case (opcjonalnie wzorzec)

if case (optional pattern) stanowi Conveni ent sposób, aby odwijać wartości opcjonalnego wyliczenia. Można go używać z krotek, aby wykonać jakiś opcjonalny łańcuchowym z wieloma zapytaniami:

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