Использование нескольких let-in внутри оператора if в 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
}
}
Но я хотел бы упаковать эти два, если пусть запросы будут в одном. Чтобы это было что-то вроде этого:
if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double {
// do stuff here
}
Этот синтаксис не работает, поэтому мне было интересно, есть ли прекрасный способ сделать это.
Ответы
Ответ 1
Обновление для 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
не будет выполнен.
Примечание. В предложениях не все должны быть предложениями "let", вы можете иметь любую последовательность логических проверок, разделенных запятыми.
Например:
if let latitudeDouble = latitude as? Double, importantThing == true {
// latitudeDouble is non-optional in here and importantThing is true
}
Swift 1.2:
Apple, возможно, прочитала ваш вопрос, потому что ваш код надежного компиляции правильно в Swift 1.2 (в бета-версии сегодня):
if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double {
// do stuff here
}
Swift 1.1 и ранее:
Вот хорошая новость - вы можете это сделать полностью. Оператор switch на кортеже двух ваших значений может использовать сопоставление с образцом для одновременного отображения обоих из них в 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")
}
Обновление: Эта версия кода теперь работает правильно.
Ответ 2
Swift 3.0
if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double {
// do stuff here
}
Ответ 3
С Swift 3 вы можете использовать необязательную цепочку, оператор switch или дополнительный шаблон, чтобы решить вашу проблему.
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. Использование кортежей и привязка значений в операторе switch
В качестве альтернативы простой необязательной цепочке оператор switch может предлагать мелкозернистую решение при использовании с кортежами и привязкой значений:
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