Temps : 30 min.
Difficulté : ***
L'objectif est d'approfondir la déclaration de variable ainsi que les collections Kotlin en 3 étapes :
En Kotlin, la nullité est sécurisée, rien n'est nul.
La ligne de code suivante ne compilera pas :
var s:String = null ❌
Cependant, il est possible de déclarer une variable nulle, en précisant
le type null
, via le symbôle ?
:
var s:String? = null
Note : Il faut alors préciser le type String?
pour une variable
de type String
.
Remarque : s
est donc une chaîne de caractère potentiellement nulle.
Dans le cas où la variable est de type null
, la ligne suivante ne compilera pas :
s.length ❌
En effet, la vérification sur la nullité est réalisé en amont de la compilation.
Afin d'accéder aux propriétés d'un objet de type nul, il y a alors deux possibilités.
Première possibilité, l'objet est possiblement nul, il s'agit d'utiliser le symbôle ?
:
s?.length
La ligne ne sera pas exécutée si s
est nul. Cela revient à :
if(s != null) {s.length}
Deuxième possibilité, l'objet n'est pas nul, il s'agit d'utiliser le symbôle !!
.
s="joker"
s!!.length
Remarque : La variable s
étant initialisé dans la ligne juste au dessus,
il est indéniable qu'elle n'est pas nulle.
Enfin, si jamais on utilise !!
alors que la variable est nulle, l'erreur
NullPointerException est produite à l'exécution.
agua.deco
, créez un nouveau fichier Deco.kt
main
, déclarez une variable String
assignée à null
:
var alga: String = null
?
, après le type afin d'indiquer que le type est potentiellement nul :
var alga: String? = null
if (alga != null)
println(alga.length)
?
, exécutez :
println(alga?.length)
println(alga?.length ?: ";)")
alga!!.length
L'initialisation tardive se fait avec le mot clé lateinit
.
Dans ce cas le développeur s'engage à initialiser la variable plus tard.
Si un accès à la variable est demandé alors qu'elle n'a pas été initialisé,
l'exception UninitializedPropertyAccessException
est lancée.
Deco.kt
, déclarez une variable lateinit
:
lateinit var fish: String
fish
:
println(fish.length)
fish = "Fish"
En Kotlin, il est courant de déconstruire des valeurs, deconstructing values,
notamment lors du traitement de liste. Ce la se fait via la déclaration multiple.
À savoir, la classe de donnée, data class
, contient d'ores déjà l'implémentation des fonctions d'opération :
component1()
component2()
component3()
agua.beach
, créez un nouveau fichier BeachBag.kt
BeachBag
:
data class BeachBag(val pocket1: String, val pocket2: String)
returnBagThings
, elle renvoie un objet BeachBag
:
fun returnBagThings(): BeachBag {
val word = "abcd"
val strId = word.reversed()
val number = (0..100).random().toString()
return BeachBag(strId, number)
}
main
, testez returnBagThings()
:
val data = returnBagThings()
println("POCKET = ${data.component1()}, MAGIC POCKET = ${data.component2()}")
val (poc1, poc2) = returnBagThings()
println("POCKET = ${poc1}, MAGIC POCKET = ${poc2}")}")
val beachParty = Array<BeachBag>(3, { returnBagThings() })
for ((poc1, poc2) in beachParty)
println("POCKET = ${poc1}, MAGIC POCKET = ${poc2}")
BeachBag.kt
Bag
:
class Bag(val p1: String = "p1", val p2: String = "p2", val p3:String="p3")
component1()
, etc :
operator fun component1():String = p1
operator fun component2():String = p2
operator fun component3():String = p3
Bag
, en testant la destructuration, dans le main
:
val (a , b, c) = Bag()
println("Bag $a $b $c")
Fun.kt
, testez le Flatmapping :
println(beachArray.flatMap { it.toList() })
val pontoon = listOf(3, 7, 9, 13, 21, 25)
average
:
println(pontoon.average())
maxOrNull
:
println(pontoon.maxOrNull())
minOrNull
:
println(pontoon.minOrNull())
count
:
println(beachArray.count
println(pontoon.count { it > 10})
count
:
println(pontoon.drop(3))
Finalement, en Kotlin