Lorsque je veux vérifier si un booléen facultatif est vrai, cela ne fonctionne pas:
var boolean : Bool? = false
if boolean{
}
Il en résulte cette erreur:
Type facultatif '@IvalueBool?' ne peut pas être utilisé comme booléen; test pour '! = nil' à la place
Je ne veux pas vérifier pour zéro; Je veux vérifier si la valeur renvoyée est vraie.
Dois-je toujours faire if boolean == true
si je travaille avec un Bool optionnel?
Puisque les options ne sont plus conformes à BooleanType
, le compilateur ne devrait-il pas savoir que je veux vérifier la valeur du booléen?
Avec des booléens optionnels, il est nécessaire de rendre la vérification explicite:
if boolean == true {
...
}
Sinon, vous pouvez ouvrir l’option facultative:
if boolean! {
...
}
Mais cela génère une exception d’exécution si booléen est nil
- pour éviter cela:
if boolean != nil && boolean! {
...
}
Avant la version 5, c'était possible, mais cela a été modifié comme indiqué dans les notes de version:
Les options ne sont plus implicitement évaluées sur true lorsqu'elles ont une valeur et sur false si elles ne le sont pas, afin d'éviter toute confusion lors de l'utilisation de valeurs Bool optionnelles. Au lieu de cela, faites une vérification explicite sur nil avec les opérateurs == ou! = Pour déterminer si un facultatif contient une valeur.
Addendum: comme suggéré par @MartinR, une variante plus compacte de la 3ème option utilise l'opérateur de coalescence:
if boolean ?? false {
// this code runs only if boolean == true
}
ce qui signifie que si booléen n'est pas nil, l'expression est évaluée à la valeur booléenne (c'est-à-dire en utilisant la valeur booléenne non enveloppée), sinon l'expression est évaluée à false
var booleanValue : Bool? = false
if let booleanValue = booleanValue, booleanValue {
// Executes when booleanValue is not nil and true
// A new constant "booleanValue: Bool" is defined and set
print("bound booleanValue: '\(booleanValue)'")
}
var booleanValue : Bool? = false
if let booleanValue = booleanValue where booleanValue {
// Executes when booleanValue is not nil and true
// A new constant "booleanValue: Bool" is defined and set
print("bound booleanValue: '\(booleanValue)'")
}
Le code let booleanValue = booleanValue
Renvoie false
si booleanValue
est nil
et que le bloc if
ne s'exécute pas. Si booleanValue
n'est pas nil
, ce code définit une nouvelle variable nommée booleanValue
de type Bool
(au lieu d'un optionnel, Bool?
) .
Le code Swift 3 & 4 booleanValue
(et le code Swift 2.2 where booleanValue
) Évalue la nouvelle variable booleanValue: Bool
. Si c'est le cas, le bloc if
s'exécute avec la variable booleanValue: Bool
Nouvellement définie (permettant à l'option de référencer à nouveau la valeur liée dans le bloc if
.).
Remarque: la convention Swift consiste à nommer la constante/variable liée de la même manière que la constante/variable optionnelle telle que let booleanValue = booleanValue
. Cette technique s'appelle observation variable. Vous pouvez rompre avec la convention et utiliser quelque chose comme let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue
. Je signale cela pour aider à comprendre ce qui se passe. Je recommande d'utiliser l'observation variable.
La coalescence nulle est claire pour ce cas particulier
var booleanValue : Bool? = false
if booleanValue ?? false {
// executes when booleanValue is true
print("optional booleanValue: '\(booleanValue)'")
}
Vérifier false
n'est pas aussi clair
var booleanValue : Bool? = false
if !(booleanValue ?? false) {
// executes when booleanValue is false
print("optional booleanValue: '\(booleanValue)'")
}
Remarque: if !booleanValue ?? false
Ne compile pas.
Le déploiement forcé augmente les chances que quelqu'un effectue un changement qui compile mais se bloque au moment de l'exécution. Par conséquent, j'éviterais quelque chose comme ceci:
var booleanValue : Bool? = false
if booleanValue != nil && booleanValue! {
// executes when booleanValue is true
print("optional booleanValue: '\(booleanValue)'")
}
Bien que cette question de débordement de pile demande spécifiquement comment vérifier si un Bool?
Correspond à true
dans une instruction if
, il est utile de définir une approche générale consistant à rechercher la valeur true, false ou à combiner la valeur non emballée avec d'autres expressions.
Au fur et à mesure que l’expression devient plus compliquée, je trouve l’approche facultative obligatoire plus souple et plus facile à comprendre que d’autres approches. Notez que la liaison facultative fonctionne avec n'importe quel type facultatif (Int?
, String?
, Etc.).