2017-02-03 4 views
7

Je suis nouveau à Kotlin et je ne sais pas pourquoi le compilateur se plaint de ce code:classes de données Kotlin et types nullables

data class Test(var data : String = "data") 

fun test(){ 
    var test: Test? = Test("") 
    var size = test?.data.length 
} 

compilateur avec test?.data.length se plaint, il est dit que je dois faire: test?.data?.length. Mais la variable de données est String, pas String?, donc je ne comprends pas pourquoi je dois mettre le ? quand je veux vérifier la longueur.

Répondre

10

L'expression test?.data.length est équivalente à (test?.data).length, et la partie test?.data peut être nulle: il est soit test.data ou null. Par conséquent, il n'est pas sûr pour obtenir son length, mais à la place, vous devez utiliser à nouveau le safe call operator: test?.data?.length.

La valeur nulle se propage à travers l'ensemble des appels chaîne: vous devez écrire ces chaînes comme a?.b?.c?.d?.e (ce qui est, encore une fois, ce qui équivaut à (((a?.b)?.c)?.d)?.e), parce que, si l'un des le reste des appels ne peuvent pas parties gauche est nulle, être effectué comme si la valeur n'était pas nulle.

+0

Ok, je comprends maintenant. Merci beaucoup! –

3

Si vous ne voulez pas utiliser l'appel en toute sécurité avant chaque composante non annulable de la chaîne d'appel, vous pouvez obtenir le résultat du premier appel en toute sécurité dans une nouvelle variable avec les fonctions d'extension standards run ou let:

// `this` is non-nullable `Test` inside lambda 
val size = test?.run { data.length } 

// or: `it` is non-nullable `Test` inside lambda 
val size = test?.let { it.data.length } 

Notez que size est toujours NULL Int? ici.

+0

Merci beaucoup! –