Formation Kotlin pour les programmeurs 2 : Principes de base de Kotlin

Cet atelier de programmation fait partie du cours Kotlin Bootcamp for Programmers. Vous tirerez pleinement parti de ce cours en suivant les ateliers de programmation dans l'ordre. En fonction de vos connaissances, vous pourrez peut-être survoler certaines sections. Ce cours s'adresse aux programmeurs qui connaissent un langage orienté objet et qui souhaitent apprendre Kotlin.

Introduction

Dans cet atelier de programmation, vous allez découvrir les principes de base du langage de programmation Kotlin : types de données, opérateurs, variables, structures de contrôle, et variables nullable et non nullable. Ce cours s'adresse aux programmeurs qui connaissent un langage orienté objet et qui souhaitent apprendre Kotlin.

Plutôt que de créer une seule application exemple, les leçons de ce cours sont conçues pour développer vos connaissances, mais sont semi-indépendantes les unes des autres afin que vous puissiez parcourir les sections que vous connaissez. Pour les relier, de nombreux exemples utilisent un thème d'aquarium. Si vous souhaitez en savoir plus sur l'histoire de l'aquarium, consultez le cours Udacity Kotlin Bootcamp for Programmers.

Ce que vous devez déjà savoir

  • Créer un projet dans IntelliJ IDEA
  • Vous savez comment ouvrir et exécuter du code dans le REPL (Read-Eval-Print Loop) de Kotlin dans IntelliJ IDEA (Tools > Kotlin > Kotlin REPL).

Points abordés

  • Utiliser les types de données, les opérateurs et les variables Kotlin
  • Utiliser des valeurs booléennes et des conditions
  • La différence entre les variables pouvant avoir ou non une valeur nulle
  • Fonctionnement des tableaux, des listes et des boucles en Kotlin

Objectifs de l'atelier

  • Utiliser le REPL Kotlin pour apprendre les bases de Kotlin

Dans cette tâche, vous allez découvrir les opérateurs et les types dans le langage de programmation Kotlin.

Étape 1 : Explorez les opérateurs numériques

  1. Ouvrez IntelliJ IDEA, s'il n'est pas déjà ouvert.
  2. Pour ouvrir le REPL Kotlin, sélectionnez Tools > Kotlin > Kotlin REPL.

Comme d'autres langages, Kotlin utilise +, -, * et / pour l'addition, la soustraction, la multiplication et la division. Kotlin accepte également différents types de nombres, tels que Int, Long, Double et Float.

  1. Saisissez les expressions suivantes dans le REPL. Pour voir le résultat, appuyez sur Control+Enter (Command+Enter sur un Mac) après chaque opération.
1+1
⇒ res8: kotlin.Int = 2

53-3
⇒ res9: kotlin.Int = 50

50/10
⇒ res10: kotlin.Int = 5

1.0/2.0
⇒ res11: kotlin.Double = 0.5

2.0*3.5
⇒ res12: kotlin.Double = 7.0

Notez que les résultats des opérations conservent les types des opérandes. Ainsi, 1/2 = 0, mais 1.0/2.0 = 0.5.

  1. Essayez des expressions avec différentes combinaisons de nombres entiers et décimaux.
6*50
⇒ res13: kotlin.Int = 300

6.0*50.0
⇒ res14: kotlin.Double = 300.0

6.0*50
⇒ res15: kotlin.Double = 300.0
  1. Appelez certaines méthodes sur des nombres. Kotlin conserve les nombres en tant que primitives, mais vous permet d'appeler des méthodes sur les nombres comme s'il s'agissait d'objets.
2.times(3)
⇒ res5: kotlin.Int = 6

3.5.plus(4)
⇒ res8: kotlin.Double = 7.5

2.4.div(2)
⇒ res9: kotlin.Double = 1.2

Étape 2 : S'entraîner à utiliser les types

Kotlin ne convertit pas implicitement les types numériques. Vous ne pouvez donc pas attribuer directement une valeur courte à une variable longue, ni un Byte à un Int. En effet, la conversion implicite des nombres est une source d'erreurs courante dans les programmes. Vous pouvez toujours attribuer des valeurs de différents types en effectuant un casting.

  1. Pour voir certains des casts possibles, définissez une variable de type Int dans le REPL.
val i: Int = 6
  1. Créez une variable, puis saisissez le nom de la variable indiqué ci-dessus, suivi de .to.
val b1 = i.to

IntelliJ IDEA affiche une liste des suggestions possibles. Cette saisie semi-automatique fonctionne pour les variables et les objets de tout type.

  1. Sélectionnez toByte() dans la liste, puis imprimez la variable.
val b1 = i.toByte()
println(b1)
⇒ 6
  1. Attribuez une valeur Byte à des variables de différents types.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1

val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected

val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected

val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
  1. Pour les attributions qui ont renvoyé des erreurs, essayez plutôt de les caster.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1

val i5: String = b2.toString()
println(i5)
⇒ 1

val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
  1. Pour rendre les longues constantes numériques plus lisibles, Kotlin vous permet de placer des traits de soulignement dans les nombres, là où cela vous semble pertinent. Essayez de saisir différentes constantes numériques.
val oneMillion = 1_000_000
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Étape 3 : Découvrez la valeur des types de variables

Kotlin accepte deux types de variables : modifiables et immuables. Avec val, vous pouvez attribuer une valeur une fois. Si vous tentez de réattribuer un élément, un message d'erreur s'affiche. Avec var, vous pouvez attribuer une valeur, puis la modifier ultérieurement dans le programme.

  1. Définissez des variables à l'aide de val et var, puis attribuez-leur de nouvelles valeurs.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned

Vous pouvez attribuer une valeur à fish, puis lui attribuer une nouvelle valeur, car elle est définie avec var. Si vous essayez d'attribuer une nouvelle valeur à aquarium, une erreur se produit, car il est défini avec val.

Le type que vous stockez dans une variable est déduit lorsque le compilateur peut le déterminer à partir du contexte. Si vous le souhaitez, vous pouvez toujours spécifier explicitement le type d'une variable à l'aide de la notation par deux-points.

  1. Définissez des variables et spécifiez explicitement le type.
var fish: Int = 12
var lakes: Double = 2.5

Une fois qu'un type a été attribué par vous ou par le compilateur, vous ne pouvez plus le modifier, sinon une erreur s'affiche.

Étape 4 : En savoir plus sur les chaînes

Les chaînes de caractères en Kotlin fonctionnent à peu près comme dans n'importe quel autre langage de programmation, en utilisant " pour les chaînes et ' pour les caractères uniques. Vous pouvez concaténer des chaînes avec l'opérateur +. Vous pouvez créer des modèles de chaîne en les combinant avec des valeurs. Le nom $variable est remplacé par le texte représentant la valeur. C'est ce qu'on appelle l'interpolation de variables.

  1. Créez un modèle de chaîne.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
  1. Créez un modèle de chaîne contenant une expression. Comme dans d'autres langages, la valeur peut être le résultat d'une expression. Utilisez des accolades {} pour définir l'expression.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants

Dans cette tâche, vous allez découvrir les booléens et la vérification des conditions dans le langage de programmation Kotlin. Comme d'autres langages, Kotlin possède des booléens et des opérateurs booléens tels que "inférieur à", "égal à", "supérieur à", etc. (<, ==, >, !=, <=, >=).

  1. Écrivez une instruction if/else.
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
    println("Good ratio!") 
} else {
    println("Unhealthy ratio")
}
⇒ Good ratio!
  1. Essayez une plage dans une instruction if. En langage Kotlin, la condition que vous testez peut également utiliser des plages.
val fish = 50
if (fish in 1..100) {
    println(fish)
}
⇒ 50
  1. Écrivez un if avec plusieurs cas. Pour les conditions plus complexes, utilisez les opérateurs logiques ET (&&) et OU (||). Comme dans d'autres langages, vous pouvez avoir plusieurs cas en utilisant else if.
if (numberOfFish == 0) {
    println("Empty tank")
} else if (numberOfFish < 40) {
    println("Got fish!")
} else {
    println("That's a lot of fish!")
}
⇒ That's a lot of fish!
  1. Essayez une instruction when. Il existe une façon plus élégante d'écrire cette série d'instructions if/else if/else en Kotlin, en utilisant l'instruction when, qui est semblable à l'instruction switch dans d'autres langages. Les conditions d'une instruction when peuvent également utiliser des plages.
when (numberOfFish) {
    0  -> println("Empty tank")
    in 1..39 -> println("Got fish!")
    else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!

Dans cette tâche, vous allez découvrir la différence entre les variables pouvant avoir ou non une valeur nulle. Les erreurs de programmation impliquant des valeurs nulles sont à l'origine d'innombrables bugs. Kotlin vise à réduire les bugs en introduisant des variables non nullable.

Étape 1 : En savoir plus sur la possibilité d'avoir une valeur nulle

Par défaut, les variables ne peuvent pas être null.

  1. Déclarez un Int et attribuez-lui null.
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
  1. Utilisez l'opérateur point d'interrogation, ?, après le type pour indiquer qu'une variable peut être nulle. Déclarez un Int? et attribuez-lui null.
var marbles: Int? = null

Lorsque vous avez des types de données complexes, comme une liste :

  • Vous pouvez autoriser les éléments de la liste à être nuls.
  • Vous pouvez autoriser la liste à être nulle, mais si elle ne l'est pas, ses éléments ne peuvent pas être nuls.
  • Vous pouvez autoriser la liste ou les éléments à être nuls.

Les listes et certains autres types de données complexes seront abordés dans une tâche ultérieure.

Étape 2 : En savoir plus sur le ? et ?: opérateurs

Vous pouvez tester null avec l'opérateur ?, ce qui vous évite d'écrire de nombreuses instructions if/else.

  1. Écrivez du code de manière plus longue pour vérifier si la variable fishFoodTreats n'est pas null. Décrémentez ensuite cette variable.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
    fishFoodTreats = fishFoodTreats.dec()
}
  1. Examinons maintenant la façon d'écrire ce code en Kotlin, à l'aide de l'opérateur ?.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
  1. Vous pouvez également enchaîner des tests de valeur nulle avec l'opérateur ?:. Prenons cet exemple :
fishFoodTreats = fishFoodTreats?.dec() ?: 0

Il s'agit d'une abréviation de "si fishFoodTreats n'est pas null, décrémentez-le et utilisez-le ; sinon, utilisez la valeur après ?:, qui est 0". Si fishFoodTreats est null, l'évaluation est arrêtée et la méthode dec() n'est pas appelée.

Remarque sur les pointeurs nuls

Si vous aimez vraiment NullPointerExceptions, Kotlin vous permet de les conserver. L'opérateur d'assertion non nul, !! (double point d'exclamation), convertit n'importe quelle valeur en type non nul et génère une exception si la valeur est null.

val len = s!!.length   // throws NullPointerException if s is null

Dans cette tâche, vous allez découvrir les tableaux et les listes, ainsi que différentes façons de créer des boucles dans le langage de programmation Kotlin.

Étape 1 : Créez des listes

Les listes sont un type fondamental en Kotlin et sont semblables aux listes dans d'autres langages.

  1. Déclarez une liste à l'aide de listOf et imprimez-la. Cette liste ne peut pas être modifiée.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
  1. Déclarez une liste qui peut être modifiée à l'aide de mutableListOf. Supprimez un élément.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true

La méthode remove() renvoie true lorsqu'elle supprime l'élément transmis.

Étape 2 : Créez des tableaux

Comme d'autres langages, Kotlin possède des tableaux. Contrairement aux listes en Kotlin, qui ont des versions modifiables et immuables, il n'existe pas de version modifiable d'un Array. Une fois que vous avez créé un tableau, sa taille est fixe. Vous ne pouvez pas ajouter ni supprimer d'éléments, sauf en les copiant dans un nouveau tableau.

Les règles d'utilisation de val et var sont les mêmes pour les tableaux que pour les listes.

  1. Déclarez un tableau de chaînes à l'aide de arrayOf. Utilisez l'utilitaire de tableau java.util.Arrays.toString() pour l'imprimer.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
  1. Un tableau déclaré avec arrayOf n'a pas de type associé aux éléments, ce qui vous permet de mélanger les types, ce qui est utile. Déclarez un tableau avec différents types.
val mix = arrayOf("fish", 2)
  1. Vous pouvez également déclarer des tableaux avec un seul type pour tous les éléments. Déclarez un tableau d'entiers à l'aide de intArrayOf(). Il existe des builders ou des fonctions d'instanciation correspondants pour les tableaux d'autres types.
val numbers = intArrayOf(1,2,3)
  1. Combinez deux tableaux avec l'opérateur +.
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
  1. Testez différentes combinaisons de tableaux et de listes imbriqués. Comme dans d'autres langages, vous pouvez imbriquer des tableaux et des listes. En d'autres termes, lorsque vous placez un tableau dans un autre, vous obtenez un tableau de tableaux, et non un tableau aplati du contenu des deux. Les éléments d'un tableau peuvent également être des listes, et les éléments de listes peuvent être des tableaux.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]

Le premier élément, numbers, est un Array. Lorsque vous n'utilisez pas l'utilitaire de tableau pour l'imprimer, Kotlin imprime l'adresse au lieu du contenu du tableau.

  1. Une fonctionnalité intéressante de Kotlin est que vous pouvez initialiser des tableaux avec du code au lieu de les initialiser à 0. Essayez cet exemple :
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]

Le code d'initialisation se trouve entre les accolades, {}. Dans le code, it fait référence à l'index du tableau, qui commence par 0.

Étape 3 : Créer des boucles

Maintenant que vous avez des listes et des tableaux, la boucle à travers les éléments fonctionne comme prévu.

  1. Créez un tableau. Utilisez une boucle for pour itérer le tableau et imprimer les éléments.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
    print(element + " ")
}
⇒ shark salmon minnow
  1. En Kotlin, vous pouvez parcourir les éléments et les index en même temps. Essayez cet exemple :
for ((index, element) in school.withIndex()) {
    println("Item at $index is $element\n")
}
⇒ Item at 0 is shark
Item at 1 is salmon
Item at 2 is minnow
  1. Essayez différentes tailles et plages de pas. Vous pouvez spécifier des plages de nombres ou de caractères, par ordre alphabétique. Comme dans d'autres langages, vous n'êtes pas obligé d'avancer d'une unité. Vous pouvez revenir en arrière à l'aide de downTo.
for (i in 1..5) print(i)
⇒ 12345

for (i in 5 downTo 1) print(i)
⇒ 54321

for (i in 3..6 step 2) print(i)
⇒ 35

for (i in 'd'..'g') print (i)
⇒ defg
  1. Essayez quelques boucles. Comme d'autres langages, Kotlin possède des boucles while, des boucles do...while et des opérateurs ++ et --. Kotlin possède également des boucles repeat.
var bubbles = 0
while (bubbles < 50) {
    bubbles++
}
println("$bubbles bubbles in the water\n")

do {
    bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")

repeat(2) {
     println("A fish is swimming")
}
⇒ 50 bubbles in the water
49 bubbles in the water
A fish is swimmingA fish is swimming

Kotlin est très semblable à d'autres langages en ce qui concerne les bases comme les opérateurs, les listes et les boucles, mais il existe quelques différences importantes.

Les fonctionnalités suivantes peuvent être différentes dans Kotlin par rapport à ce à quoi vous êtes habitué dans d'autres langages :

  • Les types Kotlin ne peuvent pas être convertis de manière implicite. Utilisez le casting.
  • Les variables déclarées avec val ne peuvent être attribuées qu'une seule fois.
  • Par défaut, les variables Kotlin ne sont pas annulables. Utilisez ? pour rendre les variables nullables.
  • Avec Kotlin, vous pouvez parcourir l'index et les éléments d'un tableau en même temps dans une boucle for.

Les constructions de programmation Kotlin suivantes sont semblables à celles d'autres langages :

  • Les tableaux et les listes peuvent être d'un seul type ou de types mixtes.
  • Les tableaux et les listes peuvent être imbriqués.
  • Vous pouvez créer des boucles avec for, while, do/while et repeat.
  • L'instruction when est la version Kotlin de l'instruction switch, mais when est plus flexible.

Documentation Kotlin

Si vous souhaitez en savoir plus sur un sujet abordé dans ce cours ou si vous êtes bloqué, https://kotlinlang.org est le meilleur point de départ.

Tutoriels Kotlin

Le site Web https://try.kotlinlang.org inclut des tutoriels complets appelés Kotlin Koans, un interpréteur Web et un ensemble complet de documentation de référence avec des exemples.

Cours Udacity

Pour consulter le cours Udacity sur ce sujet, reportez-vous à la formation Kotlin pour les programmeurs.

IntelliJ IDEA

La documentation d'IntelliJ IDEA est disponible sur le site Web de JetBrains.

Cette section répertorie les devoirs possibles pour les élèves qui suivent cet atelier de programmation dans le cadre d'un cours animé par un enseignant. Il revient à l'enseignant d'effectuer les opérations suivantes :

  • Attribuer des devoirs si nécessaire
  • Indiquer aux élèves comment rendre leurs devoirs
  • Noter les devoirs

Les enseignants peuvent utiliser ces suggestions autant qu'ils le souhaitent, et ne doivent pas hésiter à attribuer d'autres devoirs aux élèves s'ils le jugent nécessaire.

Si vous suivez cet atelier de programmation par vous-même, n'hésitez pas à utiliser ces devoirs pour tester vos connaissances.

Répondre aux questions suivantes

Question 1

Lequel des éléments suivants déclare une liste de chaînes immuable ?

▢ val school = arrayOf("shark", "salmon", "minnow")

▢ var school = arrayOf("shark", "salmon", "minnow")

▢ val school = listOf("shark", "salmon", "minnow")

▢ val school = mutableListOf("shark", "salmon", "minnow")

Question 2

Quel sera le résultat du code suivant ?
for (i in 3..8 step 2) print(i)

▢ 345678

▢ 468

▢ 38

▢ 357

Question 3

Quel est l'objectif du point d'interrogation dans ce code ?
var rocks: Int? = 3

▢ Le type de la variable rocks n'est pas fixe.

▢ La variable rocks peut être définie sur "null".

▢ La variable rocks ne peut pas être définie sur "null".

▢ La variable rocks ne doit pas être initialisée immédiatement.

Passez à la leçon suivante : 3. Fonctions

Pour obtenir un aperçu du cours, y compris des liens vers d'autres ateliers de programmation, consultez Formation Kotlin pour les programmeurs : bienvenue dans le cours.