Qu'est-ce que l'opérateur Kotlin double-bang (!!)?

178

Je convertis Java en Kotlin avec Android Studio. J'obtiens un double coup après la variable d'instance. Qu'est-ce que le double bang et surtout où est-ce documenté?

mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))
mbr_at_ml
la source

Réponses:

206

Il s'agit T?d'une conversion non sécurisée de type nullable ( ) en un type non nullable ( T), qui !!sera lancée NullPointerExceptionsi la valeur est null.

Il est documenté ici avec les moyens Kotlin de sécurité nulle.

touche de raccourci
la source
1
qu'est-ce que cela signifie lorsque le !!est à la fin d'une déclaration? IJ auto-convert to Kotlin a fait cela pour moival price = sale.latest!!
ycomp
7
@ycomp, cela signifie que sale.latestpeut contenir null; l'affectation ne réussira que si elle sale.latestn'est pas nulle et lancera NPE dans le cas contraire. Cela donne une sécurité nulle pour val price: son type sera non nul. Voir kotlinlang.org/docs/reference/null-safety.html
raccourci clavier
1
@hotkey: Alors quelle est la différence entre obtenir NPE - ici OU quand la dernière méthode est accédée sur un objet nul?
Aada
3
@Aada, c'est un problème courant de déboguer un NPE et d'avoir du mal à localiser la ligne / chemin d'exécution qui définit la valeur sur null. Cette affectation nulle pourrait se produire dans un contexte, une classe ou même un jour différent! En utilisant, !!vous pouvez échouer rapidement et localiser la cause première d'un NPE. Je souhaite que Java ait une fonctionnalité similaire (c'est-à-dire, sans ifdéclarations et / ou assertions laids ).
Cascader
82

Voici un exemple pour clarifier les choses. Dites que vous avez cette fonction

fun main(args: Array<String>) {
    var email: String
    email = null
    println(email)
}

Cela produira l'erreur de compilation suivante.

Null can not be a value of a non-null type String

Vous pouvez maintenant éviter cela en ajoutant un point d'interrogation au Stringtype pour le rendre nullable.

Donc nous avons

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email)
}

Cela produit un résultat de

null

Maintenant, si nous voulons que la fonction lève une exception lorsque la valeur de l'email est nulle, nous pouvons ajouter deux exclamations à la fin de l'email. Comme ça

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email!!)
}

Cela jettera un KotlinNullPointerException

Alf Moh
la source
5
Alors, pourquoi les gens utiliseraient-ils «!!» même si cela n'est pas sûr car une application sera arrêtée lorsque cette variable a la valeur null?
Sam
3
@david, vous ne pouvez l'utiliser que lorsque vous êtes sûr à 100% que la variable n'est pas nulle (par exemple, vous l'avez explicitement vérifiée) et que vous avez besoin d'une variable non nullable
FMK
7
@FMK je comprends, merci! Je comprends que le double bang est utilisé pour permettre aux valeurs de la variable de type Nullable d'entrer dans une variable de types non Nullable, non?
Sam
2
@david oui, exactement.
FMK
10

L'opérateur double bang est une excellente option pour les fans de NullPointerException(ou NPE pour faire court).

L' opérateur d'assertion non nul !! convertit toute valeur en un type non nul et lève une exception si la valeur est nulle.

val nonNull = a!!.length

Vous pouvez donc écrire a!!, et cela retournera une valeur non nulle de a(un Stringici par exemple) ou lancera un NPE si aest nul.

Si vous voulez un NPE, vous pouvez l'avoir, mais vous devez le demander explicitement. Cet opérateur doit être utilisé dans les cas où le développeur garantit - la valeur ne sera jamais nulle .

Andy Fedoroff
la source
2
En tant que débutant: pourquoi voudrais-je convertir une valeur en un type non nul?
Wolf359
4
@ Wolf359 Cela vous permet d'être sûr à 100% que sa valeur n'est pas nulle. ("C'est un problème courant de déboguer un NPE et d'avoir du mal à localiser la ligne / chemin d'exécution qui définit la valeur à null. Cette affectation nulle peut se produire dans un contexte, une classe ou même un jour différent!" par Cascader)
réduction de l'activité