Décorations variables Swift avec "?" (point d'interrogation) et "!" (point d'exclamation)

106

Je comprends que dans Swift toutes les variables doivent être définies avec une valeur, et qu'en utilisant des options, nous pouvons définir une variable à définir nilinitialement.

Ce que je ne comprends pas, c'est ce que fait la définition d'une variable avec a !, car j'avais l'impression que cela «déballe» une valeur d'une option. Je pensais qu'en faisant cela, vous garantissiez qu'il y avait une valeur à dérouler dans cette variable, c'est pourquoi sur IBActions et autres, vous la voyez utilisée.

Donc, en termes simples, à quoi la variable est-elle initialisée lorsque vous faites quelque chose comme ceci:

var aShape : CAShapeLayer!

Et pourquoi / quand ferais-je cela?

Jason Renaldo
la source
Vous feriez cela pour dire qu'une variable est nt nil après avoir vérifié ce fait.
Matthias
Je ne pense pas que cela devrait être marqué comme un double. "Qu'est-ce qu'une option?" n'est pas la même question que "Quelle est la différence entre les deux types d'options?" qui est à peu près ce qu'est cette question
Jiaaro
@Jiaaro même dans ce cas, il y a déjà des tonnes de questions concernant les options, les options implicitement non emballées, etc. Vous pouvez également vous référer à celui-ci: stackoverflow.com/questions/24272781/…
Jack
@JackWu Ok, mais je suis à peu près sûr que cette question n'était pas un doublon lorsqu'elle a été posée. (il a été demandé une semaine complète avant votre exemple, par exemple)
Jiaaro
@Jiaaro Vous faites un bon point, je n'ai pas remarqué que c'était plus ancien..peut-être que l'autre devrait être marqué comme un double de celui-ci à la place ..
Jack

Réponses:

145

Dans une déclaration de type, le !est similaire au ?. Les deux sont optionnels, mais le !est un optionnel " implicitement déroulé" , ce qui signifie que vous n'avez pas à le déballer pour accéder à la valeur (mais il peut toujours être nul).

C'est fondamentalement le comportement que nous avions déjà dans objective-c. Une valeur peut être nulle, et vous devez la vérifier, mais vous pouvez également accéder directement à la valeur comme si ce n'était pas facultatif (avec la différence importante que si vous ne cochez pas nil, vous obtiendrez un erreur d'exécution)

// Cannot be nil
var x: Int = 1

// The type here is not "Int", it's "Optional Int"
var y: Int? = 2

// The type here is "Implicitly Unwrapped Optional Int"
var z: Int! = 3

Usage:

// you can add x and z
x + z == 4

// ...but not x and y, because y needs to be unwrapped
x + y // error

// to add x and y you need to do:
x + y!

// but you *should* do this:
if let y_val = y {
    x + y_val
}
Jiaaro
la source
7
Les options implicitement déballées sont décrites dans une section bien nommée commençant à la page 56 du langage de programmation Swift .
Caleb
@Caleb J'ai ajouté un lien vers la section correspondante de la documentation en ligne où j'ai mentionné les options implicitement
déballées
Excellente information, merci. En général, aimer la sécurité que Swift nous impose jusqu'à présent devrait produire beaucoup moins de bugs :).
Jason Renaldo
@Jiaaro: Merci beaucoup pour le partage. Cela permet à l'utilisateur de comprendre parfaitement par l'exemple ci-dessus. !! :)
Esha
3
Je pense que la phrase « C'est fondamentalement le comportement que nous avions déjà dans l'objectif-c » peut prêter à confusion. En objective-c, on peut accéder à une nilvaleur et en fait "travailler" avec elle, en accédant rapidement à un optionnel implicitement déballé alors qu'il est nul, il lèvera une exception d'exécution.
Sascha Wolf le