web-dev-qa-db-fra.com

Pourquoi Kotlin ne permet-il pas d'utiliser Lateinit avec des types primitifs?

Dans le langage Kotlin, nous devons, par défaut, initialiser chaque variable lors de son introduction. Pour éviter cela, le mot clé lateinit peut être utilisé. La référence à une variable lateinit avant son initialisation entraîne une exception d'exécution.

lateinit ne peut cependant pas être utilisé avec les types primitifs. Pourquoi en est-il ainsi?

35
Kallja

Pour les types d'objet, Kotlin utilise la valeur null pour marquer qu'une propriété lateinit n'a pas été initialisée et pour lever l'exception appropriée lors de l'accès à la propriété.

Pour les types primitifs, il n'y a pas une telle valeur, il n'y a donc aucun moyen de marquer une propriété comme non initialisée et de fournir les diagnostics que lateinit doit fournir. (Nous pourrions essayer d'utiliser un marqueur distinct d'une certaine sorte, mais ce marqueur ne serait pas mis à jour lors de l'initialisation du champ par réflexion, ce qui est un cas d'utilisation majeur de lateinit).

Par conséquent, lateinit est pris en charge uniquement pour les propriétés des types d'objet.

34
yole

Une réponse courte est qu'avec les primitives, vous pouvez toujours utiliser 0 par défaut et avec les types nullables null par défaut. Seuls les types non primitifs non nullables peuvent avoir besoin de lateinit pour contourner le système de sécurité de type.

En fait, il n'est pas nécessaire d'initialiser une variable dans Kotlin tant qu'elle a une valeur avant le premier accès et qu'elle peut être statiquement prouvée. Ce qui signifie que ce code est parfaitement valide:

fun main(args: Array<String>) {
    var x: Int
    val y: Double

    x = 0
    y = x + 0.1

    println("$x, $y") 
}

Mais il y a des cas (rares) où l'initialisation ne peut être prouvée statiquement. Le cas le plus courant est un champ de classe qui utilise n'importe quelle forme d'injection de dépendance:

class Window {
    @Inject lateinit parent: Parent
}
2
voddan