Vérification de la valeur d’un Bool en option

Quand je veux vérifier si un Bool optionnel 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 un booléen; test pour ‘! = nil’ à la place

Je ne veux pas vérifier pour rien; 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 BooleanType ne sont plus conformes à BooleanType , le compilateur ne devrait-il pas savoir que je veux vérifier la valeur du Boolean?

Avec les booléens optionnels, il est nécessaire de rendre la vérification explicite:

 if boolean == true { ... } 

Sinon, vous pouvez déballer l’option:

 if boolean! { ... } 

Mais cela génère une exception d’exécution si booléen est nil – pour éviter que:

 if boolean != nil && boolean! { ... } 

Avant la bêta 5, c’était possible, mais il a été modifié comme indiqué dans les notes de publication:

Les options ne sont plus implicitement évaluées sur true lorsqu’elles ont une valeur et false lorsqu’elles ne le sont pas, afin d’éviter toute confusion lors de l’utilisation de valeurs Bool facultatives. Au lieu de cela, effectuez une vérification explicite contre nil avec les opérateurs == ou! = Pour savoir si une option 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: si booléen n’est pas nul, l’expression est évaluée à la valeur booléenne (c’est-à-dire en utilisant la valeur booléenne non développée), sinon l’expression est false

Reliure optionnelle

Swift 3 & 4

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

Swift 2.2

 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 Bool? facultatif 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 dans la scope (permettant de référencer à nouveau la valeur liée dans le bloc if ).

Note: Il s’agit d’une convention Swift pour nommer la constante / variable liée de la même manière que la constante / variable optionnelle telle que let booleanValue = booleanValue . Cette technique est appelée observation de variables . Vous pouvez rompre avec les conventions et utiliser quelque chose comme let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue . Je le signale pour aider à comprendre ce qui se passe. Je recommande d’utiliser l’observation variable.

Autres approches

Nude coalescer

Aucune coalescence n’est claire pour ce cas spécifique

 var booleanValue : Bool? = false if booleanValue ?? false { // executes when booleanValue is true print("optional booleanValue: '\(booleanValue)'") } 

Vérifier la présence de false n’est pas aussi clair

 var booleanValue : Bool? = false if !(booleanValue ?? false) { // executes when booleanValue is false print("optional booleanValue: '\(booleanValue)'") } 

Note: if !booleanValue ?? false if !booleanValue ?? false ne comstack pas.

Déballage forcé optionnel (éviter)

Le dépliage forcé augmente la probabilité que quelqu’un effectue un changement dans le futur qui comstack mais plante à 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)'") } 

Une approche générale

Bien que cette question de débordement de stack demande spécifiquement comment vérifier si un Bool? est true dans une instruction if , il est utile d’identifier une approche générale, que ce soit en vérifiant la valeur true, false ou en combinant la valeur non emballée avec d’autres expressions.

Au fur et à mesure que l’expression se complique, je trouve que l’approche de liaison optionnelle est plus flexible et plus facile à comprendre que les autres approches. Notez que la liaison facultative fonctionne avec tout type facultatif ( Int? Ssortingng? Etc.).

J’ai trouvé une autre solution, en surchargeant les opérateurs booléens. Par exemple:

 public func <  (left: T?, right: T) -> Bool { if let left = left { return left < right } return false } 

Cela peut ne pas être totalement dans l'esprit des changements de langage, mais cela permet de déballer en toute sécurité les options, et il est utilisable pour les conditions partout, y compris les boucles while.

J’essayais de détecter mon premier lancement d’application. Toutes les réponses précédentes où erreur de projection. Le suivant fonctionne pour moi

 if boolean { // this code runs only if boolean != nil && boolean = true }