Swift'te bir if ifadesinde birden çok let-as kullanma


144

Bir sözlükten iki değer açıyorum ve bunları kullanmadan önce onları döküp doğru türü test etmeliyim. Ben geldi budur:

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

Ama ben sorguları içine bir izin iki paketi istiyorum. Böylece böyle bir şey olur:

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

Bu sözdizimi çalışmıyor, bu yüzden bunu yapmanın güzel bir yolu olup olmadığını merak ediyordum.



Türleri eşleştirmek için bir switch deyimi kullanmanın bir yolu olabilir. Dokümanlara bir göz atın :
lomokat

Yanıtlar:


305

Swift 3 için güncelleme:

Swift 3'te aşağıdakiler çalışacaktır:

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

Sadece isteğe bağlı bağlantılardan biri başarısız olursa, if-letbloğun içindeki kodun yürütülmeyeceğini unutmayın.

Not: cümleciklerin hepsinin 'let' cümlesi olması gerekmez, virgülle ayrılmış herhangi bir dizi boolean çekiniz olabilir.

Örneğin:

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

Hızlı 1.2:

Apple sorunuzu okumuş olabilir, çünkü ümit edilen kodunuz Swift 1.2'de (bugün beta olarak) düzgün bir şekilde derlenmiştir:

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

Swift 1.1 ve öncesi:

İşte iyi haber - bunu tamamen yapabilirsiniz. İki değerinizin bir demetindeki bir switch deyimi, her ikisini Doubleaynı anda yayınlamak için desen eşleştirmeyi kullanabilir :

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

Güncelleme: Kodun bu sürümü artık düzgün çalışıyor.


6.1.1'de benim için çalışıyor, @AaronBratcher neden sana olmasın?
Daniel Gomez Rico

1
Swift 1.2'de, bunu tek bir satırda yapmak mümkün: stackoverflow.com/a/28418847/1698576
smithclay

Kodunuzda 2 seçenek kaldırılıyor. Her zaman böyle mi kullanılacak? Farklı kafa karıştırıcı kodlarım var. if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {...}. Mı 2 let ihtiyari bağlayıcı da? Yani appartık isteğe bağlı değil. sağ?
Bal

1
Bu. appartık isteğe bağlı değil, ancak windowözelliği (türü UIWindow?), bu yüzden paketini açıyorsunuz.
Nate Cook

7

Swift 3 ile sorununuzu çözmek için isteğe bağlı zincirleme, anahtarlama deyimi veya isteğe bağlı desen kullanabilirsiniz.


1. kullanma if let(isteğe bağlı bağlama / isteğe bağlı zincirleme)

Swift Programlama Dili opsiyonel zincirleme hakkında devletler:

Birden çok sorgu birlikte zincirlenebilir ve zincirdeki herhangi bir bağlantı boşsa tüm zincir zarif bir şekilde başarısız olur.

Bu nedenle, en basit durumda, isteğe bağlı zincirleme işleminizde birden çok sorgu kullanmak için aşağıdaki kalıbı kullanabilirsiniz:

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. Anahtar deyiminde tuples ve değer bağlama kullanma

Basit bir isteğe bağlı zincirlemeye alternatif olarak, switch deyimi , tuples ve değer bağlama ile kullanıldığında ince taneli bir çözüm sunabilir:

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. ile tuples kullanma if case(isteğe bağlı desen)

if case( isteğe bağlı desen ) isteğe bağlı numaralandırma değerlerinin paketinden çıkarılması için uygun bir yol sağlar. Birden fazla sorgu ile isteğe bağlı bazı zincirleme yapmak için bunu tuples ile kullanabilirsiniz:

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
Kabul edilen cevaba bir düzenleme önermelisiniz, daha düşük kaliteli bir cevap eklemeyin.
jervine10
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.