Maintenant que nous avons vu les bases de Kotlin, nous allons étudier ses différentes structures de contrôle.
Et si…
Vous devez normalement connaître aujourd’hui parfaitement la condition de type if
en Java. D’ailleurs, comme nous avons pu le voir dans la précédente partie, celle-ci en Java est une instruction (et non une expression !), et ne pourra donc jamais renvoyer de valeur.
En revanche, en Kotlin, c’est une tout autre affaire ! En effet, toutes les structures de contrôle (à l’exception des boucles) sont des expressions, et pourront donc renvoyer une valeur… :D D’ailleurs, en Kotlin, l’opérateur ternaire n’existe plus : on préférera utiliser une conditionif/else
.
int result = a > b ? a : b;
équivaut à :
val result = if (a > b) a else b
Mais ne vous inquiétez pas, utiliser la condition if
comme une expression est quelque chose dont vous prendrez l’habitude petit à petit. ;) Cela vous permettra à terme d’écrire des choses comme ceci :
var a = 10
var b = 12
val result = if (a > b){
a++
a
} else {
b++
b
}
print("Result is: $result")
et d'obtenir le résultat ci-dessous :
Oui, je sais, c’est une sacrée gymnastique intellectuelle ! :lol: De manière générale, sachez que c'est toujours la dernière expression d'un bloc qui sera retournée dans ce genre de situation.
Selon le cas…
Parfois, une condition if
n’est pas la solution la plus appropriée, notamment quand le nombre de possibilités à traiter est important et relativement structuré. Ainsi, pour pallier ce problème, nous utilisons habituellement le fameux switch
en Java :
int apiResponse = 200;
switch (apiResponse) {
case 200: System.out.print("OK");
break;
case 404: System.out.print("NOT FOUND");
break;
case 401: System.out.print("UNAUTHORIZED");
break;
case 403: System.out.print("FORBIDDEN");
break;
default: System.out.print("UNKNOWN");
break;
}
Eh bien, en Kotlin, la même chose existe, mais sous une autre identité… ;)
var apiResponse = 404
when (apiResponse) {
200 -> print("OK")
404 -> print("NOT FOUND")
401 -> print("UNAUTHORIZED")
403 -> print("FORBIDDEN")
else -> print("UNKNOWN")
}
Oui, je sais, la syntaxe a bien évolué ! Oubliez désormais l’historique switch
et utilisez à la place le mot-clé when
. :) D’ailleurs, cette structure de contrôle pourra aussi être utilisée comme une expression !
fun printResponse(apiResponse: Int) = when (apiResponse) {
200 -> print("OK")
404 -> print("NOT FOUND")
401 -> print("UNAUTHORIZED")
403 -> print("FORBIDDEN")
else -> print("UNKNOWN")
}
De plus, la structure when
en Kotlin est vraiment plus permissive que son grand frère switch
en Java :
val apiResponse = 200
when (apiResponse) {
200, 201, 202 -> print("SUCCESS")
300, 301, 302 -> print("REDIRECTION")
400, 404 -> print("ERROR")
else -> print("UNKNOWN")
}
Tellement permissive qu’elle vous permet également de ne pas spécifier de paramètre au mot-clé when
, ou même else
:
val apiResponse = 200
when {
isSuccess(apiResponse) -> print("SUCCESS")
isError(apiResponse) -> print("ERROR")
}
fun isSuccess(apiResponse: Int) = apiResponse = 200 || apiResponse = 201 || apiResponse = 202
fun isError(apiResponse: Int) = apiResponse = 400 || apiResponse = 404
Plutôt pratique, non ? :)
Vous avez dit "énumération" ?
Parfois, afin d’améliorer encore plus la lisibilité de notre code, nous utilisons les fameuses "énumérations" afin de créer des types personnalisés. D’ailleurs, reprenons notre exemple du haut, et transformons-le en une énumération (en Java et en Kotlin) :
public enum ApiResponse {
OK,
NOT_FOUND,
UNAUTHORIZED,
FORBIDDEN,
UNKNOWN;
}
enum class ApiResponse {
OK,
NOT_FOUND,
UNAUTHORIZED,
FORBIDDEN,
UNKNOWN;
}
Bon, il n’y a pas grand-chose qui change en Kotlin, avouons-le ! :) Afin de déclarer une énumération en Kotlin, vous allez devoir utiliser les mots-clés enum class
suivis du nom de votre énumération. Le corps de celle-ci restera le même qu’en Java.
De plus, vous allez également pouvoir ajouter des propriétés à votre énumération :
enum class ApiResponse(val code: Int) {
OK(200),
NOT_FOUND(404),
UNAUTHORIZED(401),
FORBIDDEN(403),
UNKNOWN(0);
}
Comme vous pouvez vous en douter, les énumérations fonctionnent très bien en combinaison avec la structure de contrôle when
, en améliorant notamment la lisibilité de notre code :
val response: ApiResponse = ApiResponse.OK
when(response){
ApiResponse.OK -> print("OK")
ApiResponse.NOT_FOUND -> print("NOT_FOUND")
ApiResponse.UNAUTHORIZED -> print("UNAUTHORIZED")
ApiResponse.FORBIDDEN -> print("FORBIDDEN")
ApiResponse.UNKNOWN -> print("UNKNOWN")
}
Pour terminer, sachez que la structure de contrôle when
est également très utilisée pour manipuler des intervalles (ou "ranges", en anglais) de nombres :
val numberToFind = 55
when(numberToFind) {
in 1..33 -> print("Number is between 1 and 33")
in 34..66 -> print("Number is between 34 and 66")
in 67..100 -> print("Number is between 67 and 100")
}
Nous en parlerons plus en détail dès le prochain chapitre… ;)
En résumé
En Kotlin, toutes les structures de contrôle (sauf les boucles) sont des expressions et peuvent retourner des valeurs.
L’opérateur ternaire n’existe plus en Kotlin, mais peut être facilement remplacé par une condition
if
.L’instruction
switch
n’existe plus en Kotlin. Celle-ci est remplacée par l'expressionwhen
, beaucoup plus concise.Pour créer une énumération en Kotlin, vous devrez utiliser les mots-clés
enum class
suivis du nom de l’énumération.
Pour aller plus loin :
KotlinLang : Control Flow
Maintenant que vous savez gérer les choix et les conditions en Kotlin, découvrons comment itérer grâce aux boucles !