# Tutoriel Kotlin : vos premiers pas avec ce nouveau langage de programmation

Disponible depuis 2016 seulement (avec la version 1.0), mais déjà très apprécié, Kotlin est une alternative à Java. Ce langage de programmation orienté objet a été développé par JetBrains, une entreprise tchèque de développement de logiciels. Il séduit de nombreux développeurs par son **caractère léger**, mais aussi par la faible survenance d’erreurs d’exécution, en particulier les erreurs *NullPointerExceptions* très redoutées. Kotlin est tout particulièrement apprécié pour le développement d’applications Android, mais rencontre également un immense succès comme base de départ pour des applications JavaScript.

Kotlin s’**inspire fortement de Java** : ces deux langages de programmation ne sont certes pas compatibles, mais Kotlin peut être transformé en bytecode lisible par une machine virtuelle Java (JVM).

## Introduction à Kotlin avec des exemples

Pour démarrer avec Kotlin, vous pouvez [télécharger ce compilateur sur le site Internet officiel](https://Kotlinlang.org/docs/tutorials/command-line.html "Tutoriel d’installation du compilateur Kotlin"). L’installation est facilitée en cas d’utilisation d’un environnement de développement (IDE) : IntelliJ IDEA (également développé par JetBrains), Eclipse (avec le plugin correspondant), NetBeans et Android Studio peuvent par exemple supporter Kotlin.

Conseil Les fabricants de Kotlin [mettent à disposition une sandbox en ligne](https://play.Kotlinlang.org/ "Kotlin Playground"), dans laquelle vous pourrez tester tous les exemples.

### Packages

Au début d’un projet, vous importez les packages dont vous avez besoin pour le réaliser. Vous définissez également le package sur lequel vous travaillez actuellement. Les packages **contiennent des classes et des fonctions**.

```none
package test.bar
import foo.bar
import footoo.bar as footoo
```

Afin d’éviter tout problème de noms identiques, Kotlin vous permet de renommer les packages avec *as*. L’**attribution d’un alias aux packages** n’impose pas de suivre la structure du répertoire dans lequel ils se trouvent. Il est toutefois recommandé de procéder de cette façon pour permettre une vue d’ensemble.

Note Kotlin charge automatiquement les principaux packages dans chaque projet.

Contrairement à Java, Kotlin vous permet également d’**importer des fonctions individuelles depuis d’autres packages**. Pour ce faire, on indique le chemin correct :

```none
import foo.bar.myFunction
```

La fonction peut ensuite être utilisée tout à fait normalement.

Conseil Dans Kotlin, il n’est pas obligatoire de terminer les lignes de code par un marqueur, par exemple un point-virgule.

### Variables

Kotlin connaît **deux types de variables** : les variables immuables, qui sont en lecture seule, sont introduites par *val*. Les autres variables, dont la valeur est modifiable au fil du programme, sont introduites par *var*.

```none
val name = "Clara Oswald"
var age = 22
```

Contrairement au nom, qui est fixe, l’âge peut être adapté, par exemple dans une fonction.

Note Dans cet exemple, Kotlin a déterminé seul le type de valeur des variables. Il est également possible d’indiquer individuellement ces types de base.

### Types de base (basic types)

Kotlin travaille avec certains types de variables et de classes. Chaque type est un objet, ce qui distingue quelque peu Kotlin de Java. Alors que les langages de programmation plus anciens doivent tout d’abord placer les types primitifs dans un [wrapper](https://www.ionos.fr/digitalguide/sites-internet/developpement-web/quest-ce-quun-wrapper/ "Qu’est-ce qu’un wrapper&nbsp;?") pour qu’ils se comportent comme des objets, avec Kotlin, c’est inutile puisque tous les types sont d’ores et déjà des objets.

#### Nombres (numbers)

Dans Kotlin, vous pouvez utiliser des nombres sans aucune balise : le compilateur comprend que ce sont des valeurs numériques. Les virgules sont réalisées à l’aide de points. Il est également possible d’utiliser des nombres hexadécimaux. Afin de permettre une meilleure lisibilité, les séparateurs de milliers sont représentés à l’aide de tirets. Kotlin connaît **différents types de nombres** pouvant tous avoir une taille maximale différente :

- Long : 64 bits
- Int : 32 bits
- Short : 16 bits
- Byte : 8 bits
- Double : 64 bits
- Float : 32 bits

Pour Double et Float, il s’agit de **nombres flottants** qui ne se comportent pas comme les nombres fixes dans des calculs complexes. Comme pour tous les types, vous pouvez indiquer des nombres de façon concrète dans votre code.

```none
val myNumber: Long = 40
```

Il est possible de convertir un nombre d’un type en nombre d’un autre type.

```none
val myInt = 600
val myLong= myInt.toLong()
```

La commande *toLong* convertit la valeur « Int » en valeur « Long ». La commande fonctionne de façon analogue pour les autres types de nombres.

#### String

Un string est un ensemble de mots ou des phrases complètes, autrement dit, une chaîne de caractères. Pour utiliser un string dans Kotlin, placez le texte entre **des guillemets doubles**. Si vous souhaitez intégrer plusieurs lignes de texte, il est nécessaire d’ajouter trois guillemets doubles au début et à la fin (raw string).

```none
val myString = "Ce string comporte une seule ligne."
val myLongString = """Ce string s'étend
sur plusieurs lignes."""
```

Comme dans de nombreux langages de programmation, Kotlin permet l’utilisation de **caractères d’échappement** : une barre oblique inversée permet de désigner un caractère ne faisant pas partie du string et devant être traité comme un caractère de contrôle. À l’inverse, une barre oblique inversée permet également d’insérer dans le string des caractères ayant normalement une autre signification dans Kotlin. Les caractères d’échappement suivants sont possibles :

- \\t : tabulation
- \\b : retour arrière
- \\n : nouvelle ligne
- \\r : retour chariot
- \\’ : guillemets simples
- \\“ : guillemets doubles
- \\\\ : barre oblique inversée
- \\$ : symbole dollar

Dans les strings, le symbole dollar sert à indiquer une **balise**. Il est possible de la définir comme variable lors d’une étape préalable. La balise est alors remplacée par une véritable valeur dans l’édition.

```none
val author = "Sandra"
val myString = "Ce texte a été écrit par $author"
```

#### Caractères (characters)

Pour certains caractères, Kotlin met également à disposition le type de données spécifique Character. Plutôt que de l’indiquer entre des guillemets doubles, on utilise des **guillemets simples**.

```none
var model = &apos;A&apos;
```

#### Boolean

Le type de base Boolean traduit une valeur de vérité qui peut être définie **sur vrai (*true*) ou faux (*false*)**.

### Arrays Kotlin

Dans Kotlin, un array est une **collection de données**. Vous pouvez construire un array avec *arrayOf()* ou *Array()*. La première de ces fonctions est simple :

```none
val myArray1 = arrayOf(0, 1, 2, 3, 4, 5)
```

On génère ainsi un array avec des chiffres de 1 à 5. Ces collections peuvent toutefois abriter d’**autres types,** comme des strings et des booleans, voire un mélange des deux. Si on souhaite limiter l’array à un type, il suffit de l’indiquer dans la fonction.

```none
val myArray2 = arrayOf<int>(10, 20, 30)</int>
val myArray3 = booleanArrayOf(true, true, false)
```

Le constructor Kotlin *Array()* est plus complexe : vous devez également indiquer la longueur et une fonction lambda.

```none
val myArray4 = Array(6, { i -> i })
```

Le constructor Kotlin génère un array avec six chiffres en commençant par zéro : 0, 1, 2, 3, 4, 5.

Note Vous en apprendrez davantage sur les constructors et les fonctions lambda dans la suite de l’article.

Chaque entrée d’un array Kotlin est indexée et peut être appelée à l’aide de cet **index**. On utilise ici des crochets dans lesquels l’emplacement comportant l’entrée dans la liste est indiqué.

```none
fun main() {
	val myArray5 = arrayOf("Jan", "Maria", "Samuel")
	println(myArray5[2])
}
```

Note La fonction indiquera dans ce cas « Samuel » puisque l’énumération commence par 0.

### Opérateurs

Comme dans de nombreux autres langages de programmation, Kotlin utilise différents opérateurs pouvant être intégrés au code source. On trouve notamment les **opérateurs arithmétiques** (+, -, \*, /, %), les **opérateurs de comparaison** (, &gt;, =, *&gt;=*, *==*, *!=*) et les **opérateurs logiques** (*&amp;&amp;*, *||*, !). Les **mots-clés** sont étroitement liés aux opérateurs. Il s’agit de termes ayant une signification fixe dans Kotlin et ne pouvant pas être réinterprétés.

Conseil Une [liste exhaustive de tous les mots-clés et opérateurs](https://Kotlinlang.org/docs/reference/keyword-reference.html "Entrée dans la documentation officielle de Kotlin") est disponible dans la documentation officielle de Kotlin.

### Intervalles (ranges)

Dans Kotlin, un Range est un type qui va d’un point à un autre. Pour générer un intervalle de ce type, on utilise l’opérateur .. ou les fonctions *rangeTo()* ou *downTo()*. La variante avec deux points permet un incrément. Les deux fonctions vous permettent en revanche de définir un sens.

```none
val range1 = 1..5
val range2 = 1.rangeTo(5)
val range3 = 5.downTo(1)
```

Dans ces deux variantes simples, vous générez un intervalle avec un incrément de un. Pour modifier l’**incrément**, ajoutez la fonction *step*.

```none
val range4 = 0..10 step(2)
```

Pour **traiter des données individuelles de l’intervalle,** utilisez l’opérateur *in*. Vous pouvez par exemple générer une requête ou une boucle. Afin de vérifier si une valeur ne fait pas partie de l’intervalle, on utilise l’opérateur *!in*.

```none
val range5 = 0..10
fun main() {
	for (n in range5) {
		println(n)
	}
	if (7 in range5) {
		println("yes")
	}
	if (12 !in range5) {
		println("no")
	}
}
```

Note Vous en apprendrez davantage sur les fonctions, les boucles et les requêtes dans la suite de l’article.

### Fonctions (functions) Kotlin

Les fonctions Kotlin sont toujours créées **avec la commande *fun***. Vous définissez ensuite le nom de la fonction, ses arguments et enfin, son effet.

```none
fun div(a: Int, b: Int): Int {
	return a/b
}
fun main() {
	println(div(100, 2))
}
```

Nous définissons dans un premier temps la fonction *div* (pour division) avec deux paramètres Int *a* et *b*. Cette fonction doit également nous donner le résultat de la division de a par b sous la forme d’une variable Int. Finalement, dans la fonction *main*, nous appelons la fonction définie précédemment, lui donnons des valeurs concrètes et affichons le résultat à l’aide de *println* (print line) dans la console. Kotlin exécute automatiquement le contenu de *main()*. Cette fonction constitue le point de départ d’un programme Kotlin.

Remarque Kotlin n’accepte aucune commande en dehors des fonctions. Seules les déclarations y sont autorisées.

Dans Kotlin, les fonctions comportant une seule ligne de code **sont facilement représentées**. Plutôt que d’ouvrir une accolade, d’écrire une nouvelle ligne intercalée et de refermer l’accolade, on utilise le symbole égal. Il est ainsi possible de se passer de la commande *return*.

```none
fun div(a: Int, b: Int): Int = a/b
fun main() = println(div(100, 2))
```

Afin d’éviter une erreur due à des paramètres erronés, vous pouvez indiquer des valeurs standard lors de la définition de la fonction. Si les paramètres sont laissés libres lors de l’appel de la fonction, les **valeurs par défaut** seront utilisées.

```none
fun div(a: Int = 10, b: Int = 5): Int = a/b
fun main() = println(div())
```

### Lambdas

Une fonction lambda (ou fonction anonyme) est une fonction qui n’appartient ni à une classe ni à un objet. Les fonctions lambda sont placées **directement dans d’autres fonctions ou variables**. Elles sont appelées sans utiliser le mot-clé *fun*. En principe, les fonctions lambda s’utilisent comme les variables de type *val* et sont également générées de cette façon.

```none
fun main() {
	val myMessage = { println("Coucou tout le monde !") }
	myMessage()
}
```

Dans Kotlin, les expressions lambda doivent toujours être placées dans des accolades et peuvent également traiter des arguments de fonction. Ces derniers sont identifiés par une **flèche** qui sépare les paramètres du noyau de l’expression.

```none
fun main() {
    val div = {a: Int, b: Int -> a/b}
    println(div(6,2))
}
```

### Classes

À l’instar de Java, les classes de Kotlin sont des **collections de données et de fonctions**. Pour définir une classe, il suffit d’utiliser le mot-clé *class* et de compléter les informations de la nouvelle classe.

```none
class Tardis {
	var year: Int
	var place: String
	constructor(year: Int, place: String) {
		this.year = year
		this.place = place
	}
}
```

Dans Kotlin, le constructor est une fonction utilisée pour créer des objets. Pour y parvenir, le langage de programmation utilise **des primary et des secondary constructors** (constructeurs primaires et secondaires). Les primary constructors sont une syntaxe abrégée pratique alors que les secondary constructors sont une forme de syntaxe similaire à celle de nombreux autres langages orientés objet dont fait notamment partie Java. Cette seconde variante est celle présentée dans l’exemple ci-dessus.

Il est toutefois possible de faire l’impasse sur le secondary constructor et d’utiliser plutôt un primary constructor. Écrivez ce constructeur directement dans la ligne d’en-tête de la classe et indiquez également les paramètres de la classe. Le nombre de lignes de code s’en trouve nettement réduit.

```none
class Tardis constructor(var year: Int, var place: String)
```

Si vous ne souhaitez pas apporter d’informations complémentaires sur la visibilité de la classe (public, private, protected), vous pouvez tout à fait vous passer entièrement du mot-clé.

```none
class Tardis (var year: Int, var place: String)
```

Ces trois exemples de code génèrent le même résultat.

Vous pouvez à présent utiliser cette classe dans le reste de votre code source et le compléter avec des valeurs concrètes.

```none
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northhampton")
```

Comme dans la plupart des langages orientés objet, vous pouvez également accéder directement aux propriétés et aux méthodes d’un objet en plaçant un point et le nom de la propriété ou de la méthode derrière l’objet.

```none
class Tardis (var year: Int, var place: String)
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northhampton")
fun main() {
    println(tardis1.year)
}
```

La **data class** constitue une particularité de Kotlin. Ce type de classe est conçu pour enregistrer uniquement des données. En principe, il suffit pour cela d’une ligne de code.

```none
data class User (var username: String, var name: String, var age: Int)
```

Cette classe peut être utilisée directement.

```none
data class User (var username: String, var name: String, var age: Int)
fun main() {
    val user1 = User ("River Song", "Melody Pond", 200)
    println("Username: " + user1.username)
    println("Name: " + user1.name)
    println("Age: " + user1.age)
}
```

### Objets (objects)

Dans Kotlin, les objets sont des instances qui ne peuvent être définies qu’une seule fois de cette façon (singleton). Ces objets **contiennent généralement des variables et des fonctions**. Ils sont en principe créés de façon similaire aux classes, c’est-à-dire avec une seule ligne de code. À sa création, l’objet est vide. Son contenu est indiqué dans le corps de l’objet.

```none
object myObject {
	fun sum(a: Int, b: Int): Int {
		return a+b
	}
}
```

### Boucles (loops)

Dans Kotlin, trois types de boucles sont disponibles : *while*, *do..while* et *if*. Elles se comportent comme leurs équivalents dans les autres langages de programmation. Une ***boucle while*** se poursuit jusqu’à ce qu’une condition déterminée survienne.

```none
fun main() {
    var n = 1
    while (n <= 10) {
        println(n++)
    }
}
```

La ***boucle do..while*** se comporte de façon similaire à la boucle *while* avec pour différence que le contenu de la boucle est parcouru au minimum une fois puisque la vérification a lieu uniquement à la fin.

```none
fun main() {
    var n = 1
    do {
        n++
    }	
    while (n < 1)
    println(n)
}
```

La **boucle *for*** se poursuit tant qu’une condition reste valable.

```none
val myRange = 0..10
fun main() {
	for (n in myRange) {
		print("$n ")
	}
}
```

### Conditions

Kotlin offre trois possibilités pour appliquer certaines instructions ou ramifications : *if*, *if..else* et *when*. La requête ***if*** permet à l’ordinateur de réaliser une tâche lorsque la condition est satisfaite.

```none
val whoCompanion = arrayOf("Bill Potts", "Clara Oswald", "Amy Pond", "Martha Jones", "Donna Noble", "Rose Tyler")
fun main() {
    if ("Rose Tyler" in whoCompanion) {
        print("yes")
    }
}
```

***else*** permet d’ajouter une action qui sera exécutée lorsque la condition n’est pas satisfaite.

```none
val whoCompanions9 = arrayOf("Rose Tyler")
val whoCompanions10 = arrayOf("Martha Jones", "Donna Noble", "Rose Tyler")
val whoCompanions11 = arrayOf("Clara Oswald", "Amy Pond")
val whoCompanions12 = arrayOf("Bill Potts", "Clara Oswald")
fun main() {
    var whoCompanion = "Clara Oswald"
    if (whoCompanion in whoCompanions9) {
        print("yes")
    }
    else {
        print("no")
    }
}
```

Finalement, l’expression ***when*** est une spécificité de Kotlin : des actions différentes sont réalisées en fonction des différents états. L’effet de l’expression *when* est ainsi similaire à ce celui de l’expression *switch* dans d’autres langages de programmation, mais il permet davantage de précision.

Placez les différents cas de vérification dans le corps de *when*. Ils sont toujours associés à une variable définie.

```none
var age = 17
fun main() {
    when {
     	age > 18 -> println("Tu es trop vieux !")
     	age == 18 -> println("Déjà adulte !")
     	age == 17 -> println("Bienvenue !")
     	age <= 16 -> println("Tu es trop jeune !")
    }
}
```

L’argument peut toutefois être transmis directement à *when* et ne doit pas être répété à chaque fois dans le corps. Par ailleurs, **une condition unique peut déclencher plusieurs actions**. Pour cela, créez un nouveau corps avec des accolades. L’expression *else* vous aidera à exclure les cas imprévus.

```none
fun multi(a: Int, b: Int, c: Int): Int {
    return a*b*c
}
fun main() {
    val d = "yes"
    when (d) {
        "no" -> println("Aucun calcul")
        "yes" -> {
            println("Démarrer le calcul") 
            println(multi(5, 2, 100))
            println("Calcul terminé")
        }
    else -> println("Saisie erronée")    
    }
}
```

### Nullability

L’**erreur *NullPointerException*** est une source de problèmes importante dans le cas d’une programmation avec Java. Cette erreur survient lorsqu’on fait référence à un objet dont la valeur est *null*. Kotlin contourne ce problème en refusant d’emblée que les variables prennent la valeur *null*. Si le cas se présentait, le message « Null can not be a value of a non-null type String » ou un autre message correspondant apparaîtrait avant la compilation.

Il existe toutefois des situations où l’on souhaite utiliser la valeur *null* à dessein. Pour y parvenir, Kotlin utilise l’**opérateur safe call** : ?.

```none
fun main() {
	var password: String? = null
	print(password)
}
```

En indiquant ce symbole, vous précisez explicitement à Kotlin que la valeur *null* est acceptable. Le programme indiquera alors *null*. Toutefois, si vous souhaitez traiter une propriété spécifique de cette variable, vous devrez de nouveau utiliser l’opérateur safe call.

```none
fun main() {
	var password: String? = null
	print(password?.length)
}
```

Ce code produira à nouveau la valeur *null*, mais aucune erreur et le programme fonctionnera. Il est toutefois plus élégant d’indiquer une valeur alternative. Pour cela, utilisez l’**opérateur Elvis** ?: ainsi nommé en raison de la banane que décrit le smiley formé par cette séquence de caractères.

```none
fun main() {
    val firstName = null
    val lastName = "Pond"
	val name: String = firstName?: "Prénom manquant" + " " + lastName?: "Nom manquant"
	print(name)
}
```

Dans cet exemple, des informations seront affichées lorsqu’une variable aura la valeur *null*.


This is a markdown version of: [https://www.ionos.fr/digitalguide/sites-internet/developpement-web/tutoriel-kotlin/](https://www.ionos.fr/digitalguide/sites-internet/developpement-web/tutoriel-kotlin/) for AI/LLM consumption.