Kotlin : les fondamentaux
La fonction main
La fonction main est le point d’entrée des programmes Kotlin, ce sont les instructions de cette fonction qui seront exécutées en premier.
Exemple avec un Hello world
fun main(args: Array<String>)
{
println("Hello world !!!")
}
Résultat :
Hello world !!!
L’exécution de ce programme permet d’afficher en console "Hello world !!!". Le mot-clé fun permet de définir une fonction. Le mot-clé main est le nom de la fonction. Les parenthèses après le nom de la fonction permettent de définir les paramètres de la fonction. Les accolades définissent le début et la fin du bloc d’instructions. La ligne println("Hello world !!!") permet d’afficher dans la console : "Hello world !!!".
Les points-virgules sont facultatifs à la fin d’une ligne d’instruction.
Les variables
1. Présentation
Une variable permet d’associer une valeur à un nom.
Le langage Kotlin est construit autour de deux paradigmes :
-
Le paradigme de la programmation orientée objet qui ne voit aucun inconvénient à utiliser des variables mutables (c’est-à-dire des variables qui peuvent changer d’état).
-
Le paradigme de la programmation fonctionnelle qui invite à utiliser des variables immutables au maximum dans le but d’éviter les effets de bord.
La première chose à faire lors de la déclaration d’une variable est de définir si elle est mutable ou immutable grâce aux mots-clés var ou val.
Ensuite, le nom de la variable doit être obligatoirement indiqué.
Le type de la variable peut être défini après deux-points (:), mais cela n’est pas obligatoire si on lui affecte une valeur au moment de sa déclaration. Effectivement, le type de la variable peut être défini explicitement après le nom de la variable, mais aussi implicitement puisque le langage Kotlin supporte l’inférence de type, ce qui permet au compilateur de déduire automatiquement le type d’une variable.
La convention de nommage pour les noms de variables est lowerCamelCase. C’est-à-dire que le nom doit être en minuscule mais chaque première lettre de chaque nouveau mot doit être en majuscule (ex. : indexCompteurPlantes).
2. Les variables immutables
Une variable immutable ne peut pas changer de valeur, elle ne peut être affectée qu’une seule fois. Le mot-clé pour définir une variable immutable est val.
Dans la mesure du possible, il est conseillé d’utiliser au maximum les variables immutables afin d’avoir un code plus concis et se rapprochant du paradigme de programmation fonctionnelle.
Exemple avec la définition explicite du type de la variable
val index : Int = 0
Dans cet exemple, la variable index est égale à 0 et est de type Int.
Exemple utilisant l’inférence de type
val index = 5
Dans cet exemple, la variable index est égale à 5 et est de type Int.
L’inférence de type ne peut pas fonctionner si aucune valeur n’est affectée à la variable.
Exemple utilisant une affectation unique, mais différée...
Les opérateurs
1. Les opérateurs arithmétiques
Voici la liste des opérateurs arithmétiques :
Opérateurs |
Description |
Exemple |
Résultat |
* |
Multiplier |
2*2 |
4 |
/ |
Diviser |
4/2 |
2 |
% |
Modulo |
5 %2 |
1 |
+ |
Additionner |
1+1 |
2 |
- |
Soustraire |
1-1 |
0 |
2. Les opérateurs de bits
Voici la liste des opérateurs de bits :
Opérateurs |
Description |
Exemple |
Résultat |
shl |
Décalage à gauche |
0b10 shl 1 |
4 |
shr |
Décalage à droite |
0b10 shr 1 |
1 |
ushr |
Décalage à droite et met les bits de gauche à zéro |
0b10 shr 1 |
1 |
and |
ET binaire |
0b10 and 0b1 |
0 |
or |
OU binaire |
0b10 or 0b1 |
3 |
xor |
Ou exclusif |
0b10 xor 0b1 |
3 |
inv |
Inversement des bits |
0b1.inv() |
-2 |
3. Les opérateurs unaires
Voici la liste des opérateurs unaires :
Opérateurs |
Description |
Exemple |
Résultat |
+ |
Addition |
2+2 |
4 |
- |
Soustraction |
2-2 |
0 |
! |
Permet d’inverser la valeur d’un booléen |
!true |
False |
++ |
Permet d’incrémenter une valeur de 1 |
var i:Int = 0 i++ |
i vaut 1 |
-- |
Permet de décrémenter une valeur de 1 |
var i:Int = 0 i-- |
i vaut -1 |
4. Les opérateurs d’affectation
Voici la liste des opérateurs d’affectation :
Opérateurs |
Description |
Exemple |
Résultat |
= |
Affectation standard |
Var x = 2 |
X est égal à 2 |
+= |
Addition |
Var x = 2 X += 2 |
X est égal à 4 |
-= |
Soustraction |
Var x = 2 X -= 2 |
X est égal à 4 |
*= |
Multiplication |
Var x = 2 X *= 2 |
X est égal à 4 |
/= |
Division |
Var x = 2 X /= 2 |
X est égal à 1 |
%= |
Modulo |
Var x = 2 X %= 2 |
X est égal à 0 |
5. Les opérateurs de comparaison
Voici la liste des opérateurs de comparaison :
Opérateurs |
Description |
Exemple |
Résultat |
== |
Égalité |
1 == 1 |
True |
!= |
Inégalité |
1 != 1 |
False |
< |
Inférieur à |
1 < 1 |
False |
> |
Supérieur à |
2>1 |
True |
<= |
Inférieur ou égal |
1<=1 |
True |
>= |
Supérieur ou égal |
2>=2 |
True |
in |
Égalité à un élément d’une multitude de valeurs |
5 in 1..10 |
True |
!in |
Inégalité à aucun élément d’une multitude de valeurs |
5 !in 1..10 |
False |
is |
Teste si une variable est d’un certain type |
5 is Int |
True |
!is |
Teste si une variable n’est pas d’un certain type |
5 !is Int |
False |
6. Les opérateurs logiques...
Les structures de contrôle
1. Les conditionnelles
Les conditionnelles permettent d’orchestrer les programmes selon certaines conditions. Il existe deux expressions conditionnelles : if et when. On parle d’"expression", car if et when peuvent retourner une valeur.
La différence entre une déclaration et une expression est que la déclaration ne peut pas retourner de valeur contrairement à l’expression.
a. L’expression if
Le if permet d’exécuter un bloc d’instructions spécifique selon le résultat de la condition qu’il a à exécuter. Le if permet aussi d’affecter une valeur spécifique à une variable selon le résultat de la condition qu’il a à exécuter.
Exemple d’utilisation simple du if
val age:Int = 80
val info:String
if(age < 18)
{
info = "Vous ne pouvez pas conduire"
}else if(age >= 18 && age < 77)
{
info = "Vous pouvez conduire"
}else{
info = "Vous ne devriez pas conduire"
}
println(info)
Résultat :
Vous ne devriez pas conduire
Exemple d’utilisation du if comme Expression
val age:Int = 15
val info:String
info = if(age < 18)
{
println("""Il est possible d'ajouter des instructions
|du moment que la dernière ligne contient
|une valeur""".trimMargin())
"Vous ne pouvez pas conduire"
}else if(age >...
Les fonctions
1. Syntaxe
Voici la syntaxe permettant de créer une fonction :
fun <nomDeLaFonction>([paramètres])[:<typeDeRetour>]
{
}
Le mot-clé fun permet de déclarer une fonction.
Paramètres |
|
nomDeLaFonction |
Par convention, il est préférable que le nom de la fonction respecte la convention de nommage lowerCamelCase. Généralement, son nom contient au moins un verbe informant sur l’action réalisée par la fonction. |
paramètres |
Liste des paramètres de la fonction. Une fonction peut contenir de zéro à plusieurs paramètres. Les paramètres sont séparés par des virgules. Tous les paramètres sont automatiquement de type val. Il n’est pas possible de définir un paramètre de type var. |
typeDeRetour |
Type de la valeur qui sera retournée par la fonction. Unit si la fonction ne retourne rien. Par défaut, le type est Unit. |
2. Usage
Les fonctions permettent de factoriser, structurer et ainsi de rendre plus maintenable une application.
Exemple simple de fonction
fun direBonjour(prenom:String):String
{
return "Bonjour $prenom"
}
La fonction se nomme direBonjour, elle attend en paramètre une variable de type String et retourne une variable de type String. Dans cet exemple, la fonction retournera "Bonjour " suivi du prénom passé en paramètre.
Si la fonction ne retourne rien, il n’est pas nécessaire de définir son type de retour.
Exemple d’une fonction ne retournant aucune valeur
fun afficherBonjour(prenom:String)
{
println("Bonjour $prenom")
}
La fonction se nomme afficherBonjour et attend en paramètre une variable de type String et ne retourne rien (c’est la raison pour laquelle le type de retour n’est pas défini). Dans cet exemple, la fonction affichera "Bonjour " suivi du prénom passé en paramètre.
L’utilisation des fonctions est similaire aux autres langages.
Exemple d’utilisation d’une fonction
fun creerBonjour(prenom:String):String
{
return "Bonjour $prenom"
}
fun main(args: Array<String>)
{
val phrase...
Les packages
1. Présentation
Un programme peut contenir des milliers de fichiers tout comme une bibliothèque peut contenir des milliers de livres. Afin de s’y retrouver, on doit classer les fichiers exactement comme on classe des livres. Pour classer des fichiers, il faut utiliser des packages qui contiendront nos différents fichiers. Par exemple, tous les fichiers permettant d’accéder à une base de données se retrouveront ensemble. Pour créer un package, il faut faire un clic droit sur le nom du projet puis sélectionner "New" puis sélectionner "Package". Il faut ensuite donner un nom au package. Le nom du package doit suivre une convention bien spécifique. Tout d’abord, il faut mettre une extension de nom de domaine comme fr, com, bzh… puis un nom. En général on utilisera le nom de l’entreprise ou du projet puis un autre nom pour détailler encore plus le contenu du package. Le but étant d’avoir un nom unique qui détaille ce qui se trouve à l’intérieur.
Quelques exemples de noms de packages
-
fr.eni.contacts.bdd
-
fr.eni.exercices
-
com.chezbatoo.devinet.ihms
Il est possible d’avoir plusieurs fichiers avec le même nom s’ils se trouvent dans des packages différents.
a. Conventions et bonnes pratiques
Respecter les conventions d’organisation et de nommage permet de réduire...
Démonstration
La démonstration suivante est un programme permettant d’afficher les nombres premiers compris entre 0 et 100.
Pour rappel, un nombre est premier s’il admet uniquement deux diviseurs différents entiers et positifs. 2, 3, 5,7 sont des nombres premiers par exemple.
/**
* Point d'entrée du programme.
*/
fun main(args: Array<String>)
{
for(nombreATester in 1..100) {
if(isPremier(nombreATester))
{
println("$nombreATester est premier")
}
}
}
/**
* Fonction permettant de déterminer si un nombre est premier.
*/
fun isPremier(nombre:Int):Boolean
{
var nombreDeDiviseur = 0;
for(i in 1..nombre)
{
if(nombre%i == 0)
{
nombreDeDiviseur++
}
}
return (nombreDeDiviseur == 2)
}