Використання декількох дозволів як у if-операторі у Swift


144

Я розгортаю два значення зі словника, і перед тим, як їх використовувати, я повинен передати їх і перевірити на правильність типу. Ось що я придумав:

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

Але я хотів би спакувати два, якщо дозволити запити в один. Так, щоб було щось подібне:

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

Цей синтаксис не працює, тому мені було цікаво, чи є гарний спосіб це зробити.



Можливо, існує спосіб використання оператора перемикання для узгодження шаблонів. Погляньте на Документи :
lomokat

Відповіді:


305

Оновлення для Swift 3:

У Swift 3 працюватимуть наступні:

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

Просто не забудьте пам’ятати, що якщо одне із спроб додаткового прив’язки не вдасться, код всередині if-letблоку не буде виконаний.

Примітка: у всіх пунктах не повинно бути "пускати", у вас може бути будь-яка серія булевих перевірок, розділених комами.

Наприклад:

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

Швидкий 1.2:

Apple, можливо, прочитала ваше запитання, оскільки ваш сподіваний код складено належним чином у Swift 1.2 (у бета-версії сьогодні):

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

Швидкий 1.1 та новіші версії:

Ось хороша новина - ви цілком можете це зробити. Оператор переключення на кордон ваших двох значень може використовувати відповідність шаблону, щоб одночасно передавати їх обом Double:

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

Оновлення: Ця версія коду зараз працює належним чином.


це працює для мене в 6.1.1, @AaronBratcher чому б вам не?
Даніель Гомес Ріко

1
В Swift 1.2, тепер можна зробити це в одному рядку: stackoverflow.com/a/28418847/1698576
smithclay

У коді у вас є 2 необов'язкові розгортання. Чи слід його використовувати завжди так? У мене різні заплутані коди. if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {...}. Є другою let також опціональний зв'язування? Я маю на увазі, appце більше не є обов'язковим. правильно?
Мед

1
Це є. appбільше не є необов’язковим, але його windowвластивість є (її тип UIWindow?), тож саме це ви розгортаєте.
Нейт Кук

7

За допомогою Swift 3 ви можете використовувати додаткове ланцюжок, оператор переключення або необов'язковий зразок, щоб вирішити свою проблему.


1. Використання if let(необов'язкове зв'язування / необов'язкове ланцюжок)

Swift Мова програмування заявляє про необов'язковою ланцюжку:

Кілька запитів можна зв'язати разом, і вся ланцюг виходить вишукано, якщо будь-яка ланка ланцюга є нульовою.

Тому в найпростішому випадку ви можете використовувати наступну схему для використання декількох запитів у вашій необов'язковій операції ланцюга:

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. Використання кортежів та прив'язки значення у операторі комутатора

Як альтернатива простому необов'язковому ланцюгу, оператор перемикача може запропонувати тонкозернисте рішення при використанні з кортежами та прив'язкою до значення:

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. Використання кортежів if case(необов'язковий візерунок)

if case( необов'язковий шаблон ) забезпечує зручний спосіб розгортання значень необов'язкового перерахування. Ви можете використовувати його з кортежами, щоб виконати кілька необов'язкових ланцюжків із кількома запитами:

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
Вам слід запропонувати змінити прийняту відповідь, не додавати ще одну відповідь нижчої якості.
jervine10
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.