Menggunakan banyak let-as dalam pernyataan if di Swift

144

Saya membuka dua nilai dari kamus dan sebelum menggunakannya saya harus memberikannya dan menguji untuk jenis yang tepat. Inilah yang saya pikirkan:

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

Tapi saya ingin mengemas keduanya jika biarkan menjadi satu. Sehingga akan seperti itu:

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

Sintaks itu tidak berfungsi, jadi saya bertanya-tanya apakah ada cara yang indah untuk melakukan itu.

Suntoch
sumber
1
kemungkinan duplikat membuka beberapa opsi dalam pernyataan if
Jack
Mungkin ada cara untuk menggunakan pernyataan switch untuk pola yang cocok dengan tipenya. Lihatlah Docs :
lomokat
1
kemungkinan duplikat dari Menggunakan "jika dibiarkan ..." dengan banyak ekspresi
rickster

Jawaban:

305

Pembaruan untuk Swift 3:

Yang berikut ini akan berfungsi di Swift 3:

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

Pastikan untuk mengingat bahwa jika salah satu binding opsional yang dicoba gagal, kode di dalam if-letblok tidak akan dieksekusi.

Catatan: klausa tidak semua harus klausa 'mari', Anda dapat memiliki serangkaian cek boolean yang dipisahkan oleh koma.

Sebagai contoh:

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

Swift 1.2:

Apple mungkin telah membaca pertanyaan Anda, karena kode yang Anda harapkan dapat dikompilasi dengan benar dalam Swift 1.2 (dalam beta hari ini):

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

Swift 1.1 dan sebelumnya:

Inilah kabar baiknya - Anda benar-benar dapat melakukan ini. Pernyataan peralihan pada tupel dari dua nilai Anda dapat menggunakan pencocokan pola untuk melakukan keduanya Doublepada saat yang sama:

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

Pembaruan: Versi kode ini sekarang berfungsi dengan baik.

Nate Cook
sumber
ini bekerja untuk saya di 6.1.1, @AaronBratcher mengapa tidak untuk Anda?
Daniel Gomez Rico
1
Di Swift 1.2, sekarang dimungkinkan untuk melakukan ini dalam satu baris: stackoverflow.com/a/28418847/1698576
smithclay
Dalam kode Anda, Anda memiliki 2 pilihan yang terbuka. Apakah akan digunakan selalu seperti itu? Saya memiliki kode membingungkan yang berbeda. if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {...}. Apakah 2nd let juga mengikat opsional? Maksud saya apptidak lagi opsional. Baik?
Sayang
1
Ini. appbukan lagi opsional, tetapi windowpropertinya adalah (tipenya UIWindow?), jadi itulah yang Anda buka.
Nate Cook
7

Dengan Swift 3, Anda dapat menggunakan perangkaian opsional, pergantian pernyataan atau pola opsional untuk menyelesaikan masalah Anda.


1. Menggunakan if let(binding opsional / chaining opsional)

The Swift Bahasa Pemrograman menyatakan tentang chaining opsional:

Beberapa kueri dapat dirantai bersama, dan seluruh rantai gagal dengan anggun jika tautan apa pun dalam rantai nol.

Oleh karena itu, dalam kasus paling sederhana, Anda dapat menggunakan pola berikut untuk menggunakan beberapa kueri dalam operasi rantai pilihan Anda:

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. Menggunakan tupel dan pengikatan nilai dalam pernyataan sakelar

Sebagai alternatif dari perangkaian opsional sederhana, pernyataan switch dapat menawarkan solusi berbutir halus ketika digunakan dengan tupel dan penjilidan nilai:

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. Menggunakan tupel dengan if case(pola opsional)

if case( pola opsional ) memberikan cara mudah untuk membuka nilai enumerasi opsional. Anda dapat menggunakannya dengan tuple untuk melakukan beberapa perangkaian opsional dengan beberapa kueri:

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
Imanou Petit
sumber
5

Swift 3.0

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double {
    // do stuff here
}
norbDEV
sumber
4
Anda harus menyarankan hasil edit ke jawaban yang diterima, jangan tambahkan jawaban berkualitas rendah lainnya.
jervine10