Que signifie "déballer l'instance" ? Pourquoi est-ce nécessaire ?
D'après ce que je sais (c'est tout nouveau pour moi aussi)...
Le terme "enveloppé" implique que nous devrions considérez une variable facultative comme un cadeau, emballé dans un papier brillant, qui pourrait (malheureusement !) être vide. .
Lorsqu'elle est "enveloppée", la valeur d'une variable facultative est un enum avec deux valeurs possibles (un peu comme un booléen). Cet enum décrit si la variable contient une valeur ( Some(T)
), ou non ( None
).
S'il y a une valeur, on peut l'obtenir en "déballant" la variable (en obtenant l'élément T
de Some(T)
).
Comment john!.apartment = number73
différent de john.apartment = number73
? (Paraphrasé)
Si vous écrivez le nom d'une variable facultative (par exemple texte john
sans le !
), cela fait référence à l'enum "enveloppé" (Some/None), et non à la valeur elle-même (T). Ainsi, john
n'est pas une instance de Person
et il n'y a pas de apartment
membre :
john.apartment
// 'Person?' does not have a member named 'apartment'
L'actuel Person
peut être déballée de différentes manières :
- "déballage forcé" :
john!
(donne le Person
si elle existe, erreur d'exécution si elle est nulle)
- "liaison facultative" :
if let p = john { println(p) }
(exécute le println
si la valeur existe)
- "chaînage optionnel" :
john?.learnAboutSwift()
(exécute cette méthode inventée si la valeur existe)
Je suppose que vous choisissez l'une de ces façons de déballer, en fonction de ce qui devrait se passer dans le cas nil, et de la probabilité que cela soit le cas. Cette conception du langage force le cas nil à être traité explicitement, ce qui, je suppose, améliore la sécurité par rapport à Obj-C (où il est facile d'oublier de traiter le cas nil).
Mise à jour :
Le point d'exclamation est également utilisé dans la syntaxe de déclaration des "optionnels implicitement non enveloppés".
Dans les exemples présentés jusqu'à présent, le john
a été déclarée comme var john:Person?
et c'est une option. Si vous voulez connaître la valeur réelle de cette variable, vous devez la déballer en utilisant l'une des trois méthodes ci-dessus.
S'il était déclaré comme var john:Person!
Au lieu de cela, la variable serait un Implicitly Unwrapped Optional (voir la section portant ce titre dans le livre d'Apple). Il n'est pas nécessaire de déballer ce type de variable lors de l'accès à la valeur, et la variable john
peuvent être utilisés sans syntaxe supplémentaire. Mais le livre d'Apple dit :
Les optionnels implicitement déballés ne doivent pas être utilisés lorsqu'il est possible qu'une variable devienne nulle ultérieurement. Utilisez toujours un type d'option normal si vous devez vérifier la présence d'une valeur nulle pendant la durée de vie d'une variable.
Mise à jour 2 :
L'article " Fonctionnalités intéressantes de Swift " par Mike Ash donne une certaine motivation pour les types optionnels. Je pense qu'il s'agit d'un excellent article, rédigé de manière claire.
Mise à jour 3 :
Un autre article utile sur le facultatif implicitement déballé utiliser pour le point d'exclamation : " Swift et le dernier kilomètre "par Chris Adamson. L'article explique qu'il s'agit d'une mesure pragmatique utilisée par Apple pour déclarer les types utilisés par ses frameworks Objective-C qui peuvent contenir nil. Déclarer un type comme optionnel (en utilisant ?
) ou implicitement déballée (en utilisant !
) est "un compromis entre la sécurité et la commodité". Dans les exemples donnés dans l'article, Apple a choisi de déclarer les types comme implicitement unwrapped, ce qui rend le code d'appel plus pratique, mais moins sûr.
Peut-être qu'Apple pourrait passer au peigne fin ses frameworks à l'avenir, en supprimant l'incertitude des paramètres implicitement déballés ("probablement jamais nil") et en les remplaçant par des déclarations optionnelles ("certainement pourrait être nil dans des circonstances particulières [espérons-le, documentées !]") ou standard non-optionnelles ("n'est jamais nil"), sur la base du comportement exact de leur code Objective-C.