Kotlin en profondeur

Temps : 30 min.
Difficulté : ***

L'objectif est d'approfondir la déclaration de variable ainsi que les collections Kotlin en 3 étapes :

  1. Gestion de variable nulle
  2. Déclaration multiple
  3. Collection avancée

1. Gestion de variable nulle

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.

  1. Dans le package agua.deco, créez un nouveau fichier Deco.kt
  2. Créez la fonction main, déclarez une variable String assignée à null :
  3.   
      var alga: String = null
      
      
  4. Essayez de compiler, quels sont les message d'IntelliJ ?
  5. Utilisez l'opérateur ?, après le type afin d'indiquer que le type est potentiellement nul :
  6.   
      var alga: String? = null
      
      
  7. Exécutez (Control + Shift + R)
  8. Affichez le nombre de caractère de la variable si elle n'est pas nulle :
  9.   
      if (alga != null)
        println(alga.length)
      
      
  10. Exécutez
  11. Épurez le code avec l'opérateur ?, exécutez :
  12.   
      println(alga?.length)
      
      
  13. Exécutez. C'est nul, utilisez plutôt l'opérateur elvis :
  14.   
      println(alga?.length ?: ";)")
      
      
  15. Provoquez l'erreur la plus répandu en Java :
  16.   
      alga!!.length
      
      

Initialisation tardive

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.

  1. Dans le fichier Deco.kt, déclarez une variable lateinit :
  2.   
      lateinit var fish: String
      
      
  3. Essayez d'afficher fish :
  4.   
      println(fish.length)
      
      
  5. Exécutez, observez
  6. Initialisez la variable avant d'accéder à ses propriétés :
  7.   
      fish = "Fish"
      
      
  8. Exécutez, observez

2. Déclaration multiple

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 :

Elles sont nécéssaire pour déconstruire les valeurs.

  1. Dans le package agua.beach, créez un nouveau fichier BeachBag.kt
  2. Créez la classe de donnée BeachBag :
  3.   
      data class BeachBag(val pocket1: String, val pocket2: String)
      
      
  4. Créez la fonction returnBagThings, elle renvoie un objet BeachBag :
  5.   
      fun returnBagThings(): BeachBag {
        val word = "abcd"
        val strId = word.reversed()
        val number = (0..100).random().toString()
        return BeachBag(strId, number)
      }
      
      
  6. Créez la fonction main, testez returnBagThings() :
  7.   
      val data = returnBagThings()
      println("POCKET = ${data.component1()}, MAGIC POCKET = ${data.component2()}")
      
      
  8. Exécutez, observez
  9. Déconstruisez les valeurs via la syntaxe :
  10.   
      val (poc1, poc2) = returnBagThings()
      println("POCKET = ${poc1}, MAGIC POCKET = ${poc2}")}")
      
      
  11. Déclarez un tableau :
  12.   
      val beachParty = Array<BeachBag>(3, { returnBagThings() })
      
      
  13. Utilisez la déconstruction de valeur pour afficher les élément du tableau :
  14.   
      for ((poc1, poc2) in beachParty)
        println("POCKET = ${poc1}, MAGIC POCKET = ${poc2}")
      
      
  15. Exécutez

  1. Dans le fichier BeachBag.kt
  2. Créez la classe Bag :
  3.   
      class Bag(val p1: String = "p1", val p2: String = "p2", val p3:String="p3")
      
      
  4. Afin de pouvoir deconstruire les valeurs créez le fonctions component1(), etc :
  5.   
      operator fun component1():String = p1
      operator fun component2():String = p2
      operator fun component3():String = p3
      
      
  6. Créez une instance de Bag, en testant la destructuration, dans le main :
  7.   
      val (a , b, c) = Bag()
      println("Bag $a $b $c")
      
      
  8. Exécutez, observez

3. Collection avancée

  1. Dans le fichier Fun.kt, testez le Flatmapping :
      
      println(beachArray.flatMap { it.toList() })
      
      
  2. Déclarez une nouvelle liste :
  3.   
      val pontoon = listOf(3, 7, 9, 13, 21, 25)
      
      
  4. Testez la function average :
  5.   
      println(pontoon.average())
      
      
  6. Exécutez, observez
  7. Testez la function maxOrNull :
  8.   
      println(pontoon.maxOrNull())
      
      
  9. Testez la function minOrNull :
  10.   
      println(pontoon.minOrNull())
      
      
  11. Testez la function count :
  12.   
      println(beachArray.count
      println(pontoon.count { it > 10})
      
      
  13. Testez la function count :
  14.   
      println(pontoon.drop(3))
      
      
  15. Exécutez, observez

Finalement, en Kotlin

Référence :

developer.android.com: Lesson 1.1 - Get started