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 if
pas une instruction switch
ou un ternaire ?
opérateur
À 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!")
}
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 ,
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.
Ce n'est pas possible.
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.
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
}