web-dev-qa-db-fra.com

Utiliser le Swift si on le laisse avec l’opérateur logique AND &&

Nous savons que nous pouvons utiliser un énoncé if let Comme un raccourci pour rechercher un éventuel nil puis le déballer.

Cependant, je veux combiner cela avec une autre expression en utilisant l'opérateur logique AND &&.

Ainsi, par exemple, je fais ici un chaînage facultatif pour dérouler et éventuellement rediffuser mon rootViewController vers tabBarController. Mais plutôt que d’avoir imbriqué des déclarations, j’aimerais les combiner.

if let tabBarController = window!.rootViewController as? UITabBarController {
    if tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
 }

Dons combinés:

if let tabBarController = window!.rootViewController as? UITabBarController &&
    tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
}

Ce qui précède donne l’erreur de compilation tilisation de l’identifiant non résolu 'tabBarController'

Simplifier:

if let tabBarController = window!.rootViewController as? UITabBarController && true {
   println("do stuff")
}

Cela donne une erreur de compilation La valeur liée dans une liaison conditionnelle doit être de type facultatif. Après avoir tenté diverses variantes syntaxiques, chacune donne une erreur de compilation différente. Je n'ai pas encore trouvé la combinaison gagnante de l'ordre et des parenthèses.

Alors, la question est, est-ce possible et si oui quelle est la syntaxe correcte?

Notez que je veux le faire avec une instruction ifpas une instruction switch ou un ternaire ? opérateur

83
Max MacLeod

À partir de Swift 1.2, ceci est maintenant possible. Les notes de publication de la version bêta de Swift 1.2 et Xcode 6. indiquent:

Développer optionnel plus puissant avec if let - La construction if let peut désormais décompresser plusieurs options en même temps, et inclure des conditions booléennes intermédiaires. Cela vous permet d'exprimer un flux de contrôle conditionnel sans imbrication inutile.

Avec la déclaration ci-dessus, la syntaxe serait alors la suivante:

if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 {
        println("do stuff")
}

Ceci utilise la clause where.

Un autre exemple, cette fois qui transforme AnyObject en Int, décompresse l’option, et vérifie que celle-ci remplit la condition suivante:

if let w = width as? Int where w < 500
{
    println("success!")
}

Pour ceux qui utilisent maintenant Swift 3, "où" a été remplacé par une virgule. L'équivalent serait donc:

if let w = width as? Int, w < 500
{
    println("success!")
}
131
Max MacLeod

Dans Swift L'exemple de Max MacLeod ressemblerait à ceci:

if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
    println("do stuff")
}

Le where a été remplacé par ,

54
ph1lb4

La réponse de Max est correcte et une façon de le faire. Notez cependant que lorsque vous écrivez de cette façon:

if let a = someOptional where someBool { }

L'expression someOptional sera résolue en premier. Si cela échoue, l'expression someBool ne sera pas évaluée (évaluation du court-circuit, comme vous le souhaiteriez).

Si vous voulez écrire ceci en sens inverse, vous pouvez le faire comme suit:

if someBool, let a = someOptional { }

Dans ce cas, someBool est évalué en premier, et l'expression someOptional n'est évaluée que si elle est vraie.

36
par

Ce n'est pas possible.

De grammaire Swift

GRAMMAIRE D'UNE DÉCLARATION IF

if-statement → if if-condition code-block else-clauseopt

si condition → expression | déclaration

else-clause → else bloc de code | else if-statement

La valeur de toute condition dans une instruction if doit avoir un type conforme au protocole BooleanType. La condition peut également être une déclaration de liaison facultative, comme indiqué dans Liaison facultative.

if-condition doit être expression ou déclaration. Vous ne pouvez pas avoir à la fois une expression et une déclaration.

let foo = bar est une déclaration, elle n’est pas évaluée à une valeur conforme à BooleanType. Il déclare une constante/variable foo.

Votre solution d'origine est assez bonne, elle est beaucoup plus lisible que de combiner les conditions.

4
Bryan Chen

Swift 4, je vais utiliser,

let i = navigationController?.viewControllers.index(of: self)
if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] {
    // access parent
}
3
Sazzad Hissain Khan