web-dev-qa-db-fra.com

Utilisation de plusieurs let-as dans une instruction if dans Swift

Je décompresse deux valeurs d'un dictionnaire et avant de les utiliser, je dois les lancer et tester le bon type. Voici ce que je suis venu avec:

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

Mais je voudrais emballer les deux si laissez requêtes dans une. Pour que ça ressemble à ça:

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

Cette syntaxe ne fonctionne pas, alors je me demandais s'il y avait une belle façon de le faire.

130
suntoch

Mise à jour pour Swift 3:

Ce qui suit fonctionnera dans Swift 3:

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

Veillez simplement à vous rappeler que si l'une des tentatives de liaison facultative échoue, le code situé à l'intérieur du bloc if-let ne sera pas exécuté.

Remarque: les clauses ne doivent pas toutes être des clauses 'let', vous pouvez avoir n'importe quelle série de vérifications booléennes séparées par des virgules.

Par exemple:

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

Swift 1.2:

Apple a peut-être lu votre question car votre code souhaité est correctement compilé dans Swift 1.2 (en version bêta aujourd'hui):

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

Swift 1.1 et versions antérieures:

Voici la bonne nouvelle - vous pouvez totalement le faire. Une instruction switch sur un tuple de vos deux valeurs peut utiliser la correspondance de modèle pour les convertir en Double en même temps:

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

Mise à jour: Cette version du code fonctionne maintenant correctement.

280
Nate Cook

Avec Swift 3, vous pouvez utiliser un chaînage optionnel, une instruction switch ou un motif facultatif afin de résoudre votre problème.


1. Utilisation de if let (liaison/chaînage en option)

Le Swift Programming Language indique à propos du chaînage facultatif:

Plusieurs requêtes peuvent être chaînées ensemble et toute la chaîne échoue normalement si l'un des liens est nul.

Par conséquent, dans le cas le plus simple, vous pouvez utiliser le modèle suivant pour utiliser plusieurs requêtes dans votre opération de chaînage facultative:

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. Utilisation des tuples et de la liaison de valeur dans une instruction switch

En guise d'alternative à un simple chaînage facultatif, instruction de commutateur peut offrir une solution à grain fin lorsqu'il est utilisé avec des n-uplets et une liaison de valeur:

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. Utilisation de tuples avec if case (motif optionnel)

if case ( modèle facultatif ) offre un moyen pratique de décompresser les valeurs de l'énumération facultative. Vous pouvez l'utiliser avec des nuplets pour effectuer un chaînage facultatif avec plusieurs requêtes:

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
6
Imanou Petit

Swift 3.0

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