Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Les fonctions

Qu’est-ce qu’une fonction ?

Le but des fonctions est de découper un programme en petits éléments logiques réutilisables. Chaque fonction a pour objectif d’accomplir une tâche (par exemple, un calcul) à partir de données que nous donnons en entrée (par exemple, un chiffre) et de produire un résultat. Les données que nous donnons en entrée d’une fonction sont appelées arguments.

En dehors de la fonction main, qui est un peu particulière, nous avons déjà eu l’occasion d’utiliser des fonctions mathématiques dans cet ouvrage. Ces fonctions correspondent parfaitement à cette description : plutôt que de réimplémenter des calculs longs et compliqués, chaque fois que nécessaire, nous pouvons utiliser une fonction qui contient la logique du calcul.

Dans l’exemple suivant, la fonction abs reçoit un seul argument qui est un nombre, calcule la valeur absolue de l’argument puis retourne le résultat, soit la valeur absolue de l’argument.

import kotlin.math.abs 
 
fun main() 
{ 
 val resultat = abs(-53) 
 print(resultat) 
} 

On appelle argument la valeur qui est passée à la fonction. Une fois dans la fonction, l’argument est appelé paramètre.

Définir une fonction

S’il est possible d’utiliser des fonctions existantes, nous allons voir qu’il est également possible d’écrire nos propres fonctions.

Pour déclarer une fonction, il convient d’écrire dans l’ordre : le mot-clé fun ; le nom de la fonction ; le ou les paramètres et leurs types s’il y a lieu, entre parenthèses ; le symbole : suivi du type de résultat renvoyé.

En guise d’exemple, écrivons une fonction qui construit une phrase à partir d’un paramètre et qui retourne cette phrase :

fun main() 
{ 
 //... 
} 
 
fun sayHello(name: String): String 
{ 
 //... 
} 

La fonction créée s’appelle sayHello. Elle accepte un paramètre dont le nom est name et qui est de type String. Elle retourne un résultat de type String.

Pour déclarer un paramètre, on utilise donc une syntaxe comparable à la déclaration d’une variable, si ce n’est que les mots-clés var ou val ne sont pas présents. Le nom du paramètre est très important, car il permet de le manipuler facilement.

Il reste une question à se poser : comment retourner un résultat ? Pour cela, il convient d’utiliser un nouveau mot-clé : return.

Complétons...

Appeler une fonction

Maintenant que nous savons écrire des fonctions, nous allons voir comment les appeler afin de les utiliser. Nous l’avons déjà fait lorsque nous avons manipulé les fonctions mathématiques au chapitre Manipuler les variables.

On appelle une fonction par son nom, on indique les arguments entre parenthèses et on stocke un éventuel retour dans une variable.

En guise d’exemple, le programme suivant appelle les fonctions displayHellodisplayWord et divide précédemment écrites :

fun main() 
{ 
 displayWord("Hey!") 
 displayHello() 
 
 val result = divide(5, 2) 
 println(result) 
} 
 
fun displayWord(word: String) 
{ 
 println(word) 
} 
 
fun displayHello() 
{ 
 println("Hello") 
} 
 
fun divide(number1: Int, number2: Int): Double 
{ 
 return number1 / number2.toDouble() 
} 

Lors de son exécution, le programme déclenche l’affichage suivant dans le terminal :

Hey! 
Hello 
2.5 

Affecter des valeurs par défaut

Il est possible d’affecter des valeurs par défaut aux paramètres des fonctions.

À quoi ça sert ?

Cela permet de rendre optionnels certains arguments en leur donnant une valeur par défaut si jamais ils sont omis au moment de l’appel.

Soit une fonction dont le but est d’afficher les nombres compris entre deux bornes avec un pas spécifique :

fun count(theMin: Int, theMax: Int, theStep: Int) 
{ 
 for (counter in theMin..theMax step theStep) 
 { 
   println(counter) 
 } 
} 

Voici une autre version dans laquelle l’argument theStep a pour valeur par défaut 1 :

fun count(theMin: Int, theMax: Int, theStep: Int = 1) 
{ 
 for (counter in theMin..theMax step theStep) 
 { 
   println(counter) 
 } 
} 

Pour définir une valeur par défaut, il convient donc de simplement réutiliser la syntaxe de l’affectation d’une valeur à une variable, via le symbole = suivi de la valeur par défaut.

Nous pouvons maintenant appeler cette méthode de plusieurs façons :

count(0, 10, 1) 
count(0, 10) 
count(0, 10, 2) 

Changeons l’ordre des arguments de la méthode pour que l’argument facultatif soit le premier argument :

fun count(theStep:...

La surcharge de fonction

Il nous reste encore une notion importante à voir sur le thème des fonctions : la surcharge de fonction.

Lorsque l’on écrit une fonction dans un programme, elle doit être unique !

Comment fait-on ?

Pour être unique, une fonction doit présenter une signature unique. Les éléments qui entrent en compte dans la signature d’une fonction sont son nom, le nombre de paramètres et les types des paramètres.

Il est donc possible de définir plusieurs fonctions portant le même nom tant que le nombre de paramètres est différent ou que les types des paramètres sont différents :

fun count() 
{ 
 //... 
} 
 
fun count(min: Int, max: Int) 
{ 
 //... 
} 
 
fun count (min: Double, max: Double) 
{ 
 //... 
} 
 
fun count (min: Int, max: Double) 
{ 
 //... 
} 

Il est possible d’appeler toutes ces fonctions ! En fonction des arguments que nous allons passer, la bonne fonction sera automatiquement sélectionnée :

count() 
count(5, 10) 
count(5.0, 10.0) 
count(5, 10.0) 

Aller plus loin

1. Les paramètres sont en lecture seule

Les paramètres d’une fonction sont des variables de type "lecture seule". Cela signifie qu’il n’est pas possible de modifier leur valeur au sein de la fonction.

Par exemple, si l’on souhaite écrire une fonction qui incrémente une variable, l’implémentation suivante ne fonctionne pas :

fun increment(number: Int): Int 
{ 
 number++ 
 
 return number 
} 

En revanche, celle-ci fonctionne :

fun increment(number: Int): Int 
{ 
  return number + 1 
} 

2. Une écriture raccourcie

Dans certains cas, il est possible d’utiliser une écriture raccourcie pour écrire une fonction.

En effet, quand le corps d’une fonction (la partie qui se trouve entre accolades) n’est composée que d’une unique instruction return, il est possible de remplacer les accolades et le mot-clé return par le symbole =.

Reprenons la méthode increment précédemment écrite :

fun increment(number: Int): Int 
{ 
  return number + 1 
} 

Avec la syntaxe raccourcie, elle se résume à :

fun increment(number: Int): Int = 
   number + 1 

Il est même possible de se passer du type de retour :

fun increment(number: Int) = 
   number...

En résumé

  • Une fonction est un morceau de code réutilisable qui a pour objectif d’effectuer une tâche.

  • Une fonction est définie par un nom, des paramètres et éventuellement un résultat.

  • Il est possible de donner des valeurs par défaut à des paramètres pour les rendre facultatifs à l’appel.

  • Il est possible de créer plusieurs fonctions avec le même nom tant que leurs signatures sont différentes.