Mis à jour le lundi 30 octobre 2017
  • 30 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Créez vos premières fonctions

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Bravo ! Notre programme commence à avoir une chouette tête !‌

J'ai eu des nouvelles de Joe. Il n'a pas eu le temps de passer vous voir mais sachez qu'il est très reconnaissant de ce que vous faites pour lui. Il a déjà acheté ses palmes... :p

Je vais vous embêter mais je crois qu'on peut faire mieux que ça. Et on va découvrir comment les fonctions nous permettent de rendre notre code magnifique et extrêmement clair !

La mocheté

Notre code a commencé à pas mal s'étoffer et du coup il est de moins en moins facile à lire pour un débutant. Si vous le montrez à vos amis non programmeurs, je suis à peu près certain qu'ils auraient du mal à le lire.

Et puis même entre programmeurs, il est très important d'avoir un code d'une très grande clarté. Prenons un exemple :

// On calcule la taille de la grange
var barnSize = 0
for (goods, count) in barn {
    barnSize += count
}

Avec ce code, nous calculons la taille de la grange, c'est-à-dire le nombre de produits qu'elle contient. Et si au lieu d'écrire tout ceci, nous écrivions simplement :

calculateBarnSize

Ce serait beau quand même ! Je vous vois déjà saliver !

On va pouvoir le faire avec les fonctions, c'est fou ça ! Alors, allons-y !

Présentation des fonctions

Une fonction c'est une brique d'instructions que l'on regroupe derrière un nom. Ça ressemble à ça :

On va donc attribuer un nom à plusieurs lignes du programme. Cela permet d'avoir une plus grande clarté du code.

Par exemple, écrivons une fonction qui affiche un message d'accueil :

func souhaiterLaBienvenue() {
    print("Bienvenue dans mon super programme, je suis ravi de vous voir !")
}

 En détail, pour écrire une fonction, il faut :

  1. Écrire le mot-clé  func .

  2. Écrire le nom de la fonction, ici  souhaiterLaBienvenue . On peut choisir ce qu'on veut du moment que cela décrit clairement ce que fait la fonction.

  3. Écrire des parenthèses  () .

  4. Le contenu de la fonction s'écrit entre accolades  {} .

Si on exécute ce programme, il ne va rien se passer. Ne soyez pas déçu, c'est juste qu'on n'a fait que définir la fonction, on ne l'a pas encore appelée.

Pour appeler une fonction, on écrit le nom de la fonction suivi de parenthèses :

// Je définis la fonction
func souhaiterLaBienvenue() {
    print("Bienvenue dans mon super programme, je suis ravi de vous voir !")
}

// J'appelle la fonction
souhaiterLaBienvenue()

Cette fois-ci le programme va bien me renvoyer :

Bienvenue dans mon super programme, je suis ravi de vous voir !

Il y a donc deux étapes dans la vie d'une fonction :

  1. Sa définition : on associe un nom à une ou plusieurs lignes de code.

  2. Son appel : le contenu de la fonction est effectivement exécuté.

La portée d'une variable

Essayons d'écrire notre fonction  calculateBarnSize . On va donc placer les lignes correspondantes dans une fonction comme ceci :

func calculateBarnSize() {
    // On calcule la taille de la grange
    var barnSize = 0
    for (goods, count) in barn {
        barnSize += count
    }
}

Vous pouvez placer cette fonction juste avant la boucle while. Il nous suffit maintenant de remplacer le code correspondant dans notre boucle  while .

while money < price {
    // Joe nourrit les vaches tous les jours
    money -= 4

    calculateBarnSize()

    if barnSize >= 500 {

Je vous invite à le faire. Allez-y ! Ça marche ? Super ! Alors, passons à la...

Hop hop hop ! Pas si vite, ça ne marche pas ton truc j'ai une erreur qui dit :

error: use of unresolved identifier 'barnSize'

J'avoue, je vous ai un peu testé. En effet, on ne peut pas écrire ça comme ça directement. Quelle est donc cette erreur ? Elle indique que la variable  barnSize n'existe pas.

Mais si elle existe ! Elle est déclarée à l'intérieur de la fonction   calculateBarnSize !

Oui mais... ce n'est pas suffisant ! Et pour comprendre cela, il faut que je vous explique ce qu'est la portée d'une variable.

En fait, une variable n'existe que dans le contexte dans lequel elle a été déclarée. Un contexte a pour limite des accolades. Par exemple, prenons le programme suivant :

var age = 12

while age < 21 {
    var message = "Je suis mineur aux USA"

    if age >= 18 {
        let majoriteDepuis = age - 18
        message += " mais majeur en France depuis \(majoriteDepuis) an(s) !"
    }

    print(message)
    age += 1
}

print("Enfin la majorité absolue !")

Ce petit programme démarre à l'âge 12. À chaque tour dans la boucle while, la variable  age s'incrémente d'une année. Cette variable est utilisée pour créer une phrase qui donne le statut légal de la personne chaque année. La console affiche ceci :

Je suis mineur aux USA
Je suis mineur aux USA
Je suis mineur aux USA
Je suis mineur aux USA
Je suis mineur aux USA
Je suis mineur aux USA
Je suis mineur aux USA mais majeur en France depuis 0 an(s) !
Je suis mineur aux USA mais majeur en France depuis 1 an(s) !
Je suis mineur aux USA mais majeur en France depuis 2 an(s) !
Enfin la majorité absolue !

Je vous invite à copier-coller le code pour vous assurer que vous le comprenez correctement.

Dans ce code, on a plusieurs fois des accolades qui définissent trois contextes différents : 

Il y a trois variables dans ce code. Chacune est définie dans un contexte différent. Et elle est du coup disponible uniquement à l'intérieur de ce contexte. Donc dans ce schéma :

  • La variable  age est définie dans le contexte 1 et est donc disponible dans les contextes 1, 2, 3 car les contextes 2 et 3 sont inclus dans le 1er.

  • La variable  message  est définie dans le contexte 2 et est donc disponible dans le contexte 2 et 3. Mais pas le 1er.

  • La variable  majoriteDepuis est définie dans le contexte 3 et est donc disponible uniquement dans ce contexte

Donc quand on écrit une variable à l'intérieur d'une fonction, la variable existe uniquement dans le contexte de cette fonction, entre les accolades. Mais pas en dehors. Voilà pourquoi le programme nous dit que la variable n'est pas définie.

Pour résumer : une variable définie entre accolades  {}  n'est pas disponible en dehors de ces accolades.

La valeur de retour

Maintenant que nous avons compris notre erreur, nous allons pouvoir la résoudre. Une façon rapide de le faire serait de sortir la déclaration  var barnSize = 0 de notre fonction. Comme cela la variable serait disponible dans le contexte le plus global à savoir tout le fichier.

Vous pouvez essayer... Mais on va faire mieux !

Une fonction qui renvoie quelque chose

On a vu pour l'instant l'usage le plus simple d'une fonction : regrouper des lignes de code derrière un nom. Mais une fonction peut aussi renvoyer une information. Par exemple, faire un calcul et renvoyer le résultat de ce calcul. 

Pour cela, il suffit de préciser à la déclaration de la fonction le type de valeur renvoyé. La fonction ressemble du coup à :

La fonction calculateBarnSize renvoie une valeur de type Int
La fonction calculateBarnSize renvoie une valeur de type Int

La syntaxe pour préciser le type de la valeur s'écrit comme suit  :

func calculateBarnSize() -> Int {
    // Implementation de la fonction
}

Si vous rajoutez seulement ceci, Swift va renvoyer une erreur. Car vous venez de déclarer une fonction qui renvoie une valeur de type  Int mais en inspectant la fonction Swift ne voit pas de valeur de retour donc il n'est pas content !

Le mot-clé return

Pour renvoyer effectivement une valeur, on va utiliser le mot-clé  return . Comme ceci :

func calculateBarnSize() -> Int {
    // On calcule la taille de la grange
    var barnSize = 0
    for (goods, count) in barn {
        barnSize += count
    }
    
    return barnSize // On retourne la taille de la grange
}

Une fois la taille de la grange calculée, on utilise le mot-clé  return pour la renvoyer. Ensuite si on appelle, la fonction  calculateBarnSize() , elle va donc renvoyer la taille de la grange.

Utilisation

Pour réparer notre programme, on va pouvoir écrire :

while money < price {
    // Joe nourrit les vaches tous les jours
    money -= 4

    var barnSize = calculateBarnSize()

    if barnSize >= 500 {

La variable  barnSize  va contenir la valeur renvoyée par la fonction  calculateBarnSize . L'instruction  calculateBarnSize()  se comporte d'ailleurs exactement comme une variable de type  Int . Donc on peut même écrire directement :

while money < price {
    // Joe nourrit les vaches tous les jours
    money -= 4

    if calculateBarnSize() >= 500 {

Et voilà, c'est plus concis et plus clair comme ça !

Implémentation

Bon allez, à vous de jouer ! Réécrivez le programme en définissant les fonctions suivantes :

feedCows  // Joe nourrit les vaches
sell      // Joe vends ses produits
harvest   // Joe moissone
mowSheep  // Joe tonds les moutons
milkCows  // Joe traie les vaches

Vous êtes prêts ?

// On ne triche pas ! :D








































// Le prix du voyage
let price = 1499.0

// L'argent de Joe
var money = 0.0

// Le nombre de jours pendant lesquels Joe doit économiser
var numberOfDay = 0

// La grange de Joe : [lait, blé, laine]
var barn = ["milk": 0, "wheat": 0, "wool": 0]

func calculateBarnSize() -> Int {
    var barnSize = 0

    for (_, count) in barn {
        barnSize += count
    }

    return barnSize
}

func feedCows() {
    money -= 4
}

func sell() {
    money += Double(barn["milk"]!) * 0.50
    money += Double(barn["wheat"]!) * 0.30
    money += Double(barn["wool"]!) * 1

    // On vide la grange
    barn = ["milk": 0, "wheat": 0, "wool": 0]
}

func harvest() {
    barn["wheat"]! += 100
}

func mowSheep() {
    barn["wool"]! += 30
}

func milkCows() {
    barn["milk"]! += 30
}

while money < price {
    feedCows()

    if calculateBarnSize() >= 500 {
        sell()
    } else {
        if numberOfDay % 30 == 1 {
            harvest()
        } else if numberOfDay % 30 == 10 || numberOfDay % 30 == 20 {
            mowSheep()
        } else {
            milkCows()
        }
    }

    // On passe au jour suivant
    numberOfDay += 1
}


print("Il aura fallu \(numberOfDay) jours à Joe pour économiser \(money) €")

Félicitations vous maîtrisez les fonctions ! Votre code est quand même bien plus lisible comme ça non ?

En Résumé

  • Une fonction est une brique d'instructions que l'on regroupe derrière un nom.

  • On déclare une fonction avec le mot-clé  func  comme ceci :

    func nomDeLaFonction() {
        // Implémentation
    }
  • Une fonction peut avoir une valeur de retour. Pour cela, il faut préciser son type dans la déclaration comme ceci :

    func nomDeMaFonction() -> Type {
        // Implementation
        return valeur
    }
  • Une variable n'existe que dans le contexte dans lequel (les accolades à l'intérieur desquelles) elle a été définie.

 

Exemple de certificat de réussite
Exemple de certificat de réussite