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


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
}

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



可能存在一种使用switch语句对类型进行模式匹配的方法。看看Docs
lomokat 2014年

Answers:


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则不会执行该块内的代码。

注意:这些子句不必全部都是'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(今天为beta)中正确编译:

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

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


它在6.1.1中对我有效,@ AaronBratcher为什么对您不起作用?
Daniel Gomez Rico 2015年

1
在Swift 1.2中,现在可以在一行中完成此操作:stackoverflow.com/a/28418847/1698576
smithclay

在您的代码中,有2个可选项被展开。总是那样使用吗?我有不同的代码。if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {...}。是第2次 let也是可选的约束力?我的意思app是不再是可选的。对?
蜂蜜

1
它是。app不再是可选的,而是其window属性为(其类型为UIWindow?),所以这就是您要展开的内容。
Nate Cook

7

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


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

斯威夫特编程语言阐明有关可选链接:

可以将多个查询链接在一起,如果链中的任何链接为nil,则整个链都会正常失败。

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

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

5

斯威夫特3.0

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

4
您应该建议对接受的答案进行编辑,不要添加其他质量较低的答案。
jervine10
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.