Using multiple let-as within a if-statement in Swift

大憨熊 提交于 2019-12-17 17:26:21

问题


I'm unwrapping two values from a dictionary and before using them I have to cast them and test for the right type. This is what I came up with:

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

But I would like to pack the two if let queries into one. So that it would something like that:

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

That syntax is not working, so I was wondering if there was a beautiful way to do that.


回答1:


Update for Swift 3:

The following will work in Swift 3:

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

Just be sure to remember that if one of the attempted optional bindings fail, the code inside the if-let block won't be executed.

Note: the clauses don't all have to be 'let' clauses, you can have any series of boolean checks separated by commas.

For example:

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

Swift 1.2:

Apple may have read your question, because your hoped-for code compiles properly in Swift 1.2 (in beta today):

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

Swift 1.1 and earlier:

Here's the good news - you can totally do this. A switch statement on a tuple of your two values can use pattern-matching to cast both of them to Double at the same time:

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

Update: This version of the code now works properly.




回答2:


With Swift 3, you can use optional chaining, switch statement or optional pattern in order to solve your problem.


1. Using if let (optional binding / optional chaining)

The Swift Programming Language states about optional chaining:

Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

Therefore, in the simplest case, you can use the following pattern to use multiple queries in your optional chaining operation:

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. Using tuples and value binding in a switch statement

As an alternative to a simple optional chaining, switch statement can offer a fine grained solution when used with tuples and value binding:

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. Using tuples with if case (optional pattern)

if case (optional pattern) provides a convenient way to unwrapped the values of optional enumeration. You can use it with tuples in order to perform some optional chaining with multiple queries:

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



回答3:


Swift 3.0

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


来源:https://stackoverflow.com/questions/24592004/using-multiple-let-as-within-a-if-statement-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!