在 Swift 中的 if 语句中使用多个 let-as

我正在从字典中取出两个值,在使用它们之前,我必须对它们进行强制转换并测试正确的类型。这是我想到的:

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 查询放在一个里面,这样它就会像这样:

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

这种语法不起作用,所以我想知道是否有一种漂亮的方法可以做到这一点。

83478 次浏览

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
}

迅捷1.2:

苹果可能已经读过你的问题,因为你希望的代码在 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")
}

更新: 这个版本的代码现在可以正常工作了。

Swift 3.0

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

使用 Swift 3,您可以使用可选的链接、 switch 语句或可选模式来解决您的问题。


1. 使用 if let(可选绑定/可选链接)

快速编程语言规定了可选的链接:

可以将多个查询链接在一起,如果链中的任何链接为零,则整个链将优雅地失败。

因此,在最简单的情况下,可以使用以下模式在可选的链接操作中使用多个查询:

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 语句中使用元组和值绑定

作为简单可选链接的替代方案,开关语句可以在与元组和值绑定一起使用时提供细粒度的解决方案:

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