32 votes

Pourquoi le type de null + null est-il implicitement String en Kotlin ?

Le code Kotlin suivant :

val x = null + null

résulte en x étant de type String ce qui est correct car, selon la documentation de l'application String.plus :

Concatène cette chaîne avec la représentation de la chaîne de l'objet [autre] donné. Si le récepteur ou l'objet [autre] sont nuls, ils sont représentés par la chaîne "null".

Cependant, je ne comprends pas pourquoi cela se produit - est-ce dû à une caractéristique particulière de la langue ?

46voto

BakaWaii Points 3833

Probablement parce que String?.plus(Any?) est le seul plus qui accepte un type nullable comme récepteur dans la bibliothèque Kotlin. Par conséquent, lorsque vous appelez null + null le compilateur traitera le premier null comme String? .

Si vous définissez une fonction d'extension où le type de récepteur est Int? et le type de retour est Int alors x sera déduit comme Int .

public operator fun Int?.plus(other: Any?): Int = 1
val x = null + null

Si vous déclarez une autre fonction similaire dans le même fichier (type nullable comme type de récepteur), lorsque vous appelez null + null il provoque une erreur de compilation : Overload resolution ambiguity. All these functions match. .

public operator fun Int?.plus(other: Any?): Int = 1
public operator fun Float?.plus(other: Any?): Float = 1F
val x = null + null    //compile time error

6voto

Adel Nizamutdinov Points 627

Nous devons commencer par le type de Nothing . Ce type a exactement zéro valeur possible. C'est un type de fond et est un sous-type de chaque autre type (à ne pas confondre avec Any qui est un supertype de tout autre type ). Nothing peut être contraint à n'importe quel type, de sorte que vous pouvez faire des choses comme :

fun doStuff(a: Int): String =
    TODO("this typechecks")

Passons maintenant au type de Nothing? c'est-à-dire Nothing ou null . Il a 0 + 1 valeurs possibles. Donc null a un type de Nothing? . Nothing? peut être converti en n'importe quel type nullable, de sorte que vous pouvez faire des choses comme :

var name: String? = null

Ici null : Nothing? est contraint de String? .

Pour une raison quelconque, malheureusement, il y a cette fonction définie dans stdlib :

operator fun String?.plus(other: Any?): String

qui permet null + null en s'appuyant sur les règles de coercition que j'ai mentionnées plus haut.

4voto

Henry Points 3697
val x = null + null

Essayez de reformuler cette phrase comme suit et vous trouverez votre réponse :

val x = null.plus(null)

Ce qui suit est ce qu'IntelliJ montre comme étant la signature de la commande plus méthode :

public operator fun String?.plus(other: Any?): String

Donc le premier null est traité comme String? et ensuite, lorsque vous essayez d'ajouter quelque chose d'autre, le problème ci-dessus se pose. plus est la seule méthode que vous avez. Impression x aura pour résultat nullnull

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X