3

Commencer avec Swift : les fonctions

Cet article n'a pas été mis à jour depuis plus d'un an, il est possible que certaines informations ne soient plus à jour. Si vous rencontrez des erreurs ou des différences en le suivant, n'hésitez pas à commenter pour me le signaler.

Bonjour les adorateurs de Swift, aujourd’hui je vais vous présenter les fonctions et leur fonctionnement (lol). Pour ceux qui ont leur gyrophare “Alerte mathématiques” qui s’est allumé, pas de panique, on ne va pas faire de maths, on va juste leur emprunter un concept qui va s’avérer tout aussi fondamental que les variables ou les conditions par exemple (et qui sont eux aussi emprunté au maths). Alors c’est parti !

La fonction y = sin(cos(tan(x))) * sin(cos(tan(y)))

A quoi ça sert ?

Les fonctions sont un moyen d’exécuter un morceau spécifique de code à volonté, et en fonction de certains paramètres. Elles permettent de regrouper certaines actions répétitives en une seule commande pour éviter d’avoir à réécrire tout le code. Par exemple imaginons que nous souhaitions réaliser un script de caisse enregistreuse de fruits et légumes (la classe !), on aurait besoin de quelque chose comme ça :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// L'argent actuellement en caisse (type Int)
var argent = 10  

// Ce que l'on a en magasin (type dictionnaire [String: Int])
var stockFruits = ["pommes" : 10, "poires" : 10, "scoubidous" : 20]

/*  Le prix de chaque produit
On défini ici le type de variable car il est nécessaire de le préciser
pour les tests plus loin */

var prix:[String: Int] = ["pommes" : 2, "poires": 4, "scoubidous" : 1]


// --- Vente d'une pomme ---

/* On teste d'abord si le dictionnaire des stock contient bien l'index
"pommes" et si c'est le cas, la valeur sera stockée dans la constante stock */

if let stock = stockFruits["pommes"] {

    // Si on a du stock
    if stock > 0 {
       
        // Si l'index "pommes" existe dans le dictionnaire prix
        if let prixAPayer = prix["pommes"] {
           
            // On ajoute le prix à payer dans l'argent de la caisse
            argent += prixAPayer
            // On enlève une pomme du stock
            stockFruits["pommes"] = stock - 1
        }
    }
}

Même sans commentaires, ce code est plutôt long, et il est nécessaire de l’exécuter plusieurs fois si l’on souhaite vendre plus de produits, et il serait très long de tout réécrire à chaque fois. Cela augmenterai également le taux d’erreurs dans le code et diminuerai fortement sa lisibilité. il est donc possible de déclarer une fonction qui effectuera la vente en fonction du produit qu’on lui indiquera.

Anatomie d’une fonction

Une fonction se déclare avec le mot-clé func suivi du nom de la fonction. Les noms de fonctions sont restreints aux même possibilités que les noms de variables. Accolé au nom s’en suivent des parenthèses contenant les paramètres passés à la fonction sous forme de constantes séparées par des virgules. Chaque constante doit être nommée et son type déclaré et elles seront accessibles dans la fonction. Puis le code a exécuter se situe entre accolades.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var argent = 10
var stockFruits = ["pommes" : 10, "poires" : 10, "scoubidous" : 20]
var prix:[String: Int] = ["pommes" : 2, "poires": 4, "scoubidous" : 1]

func vendre(fruit:String) {
    if let stock = stockFruits[fruit] {
        if stock > 0 {
            if let prixAPayer = prix[fruit] {
                argent += prixAPayer
                stockFruits[fruit] = stock + 1
            }
        }
    }
}

// Vente d'une pomme
vendre(fruit: "pommes")

// Vente d'une poire
vendre(fruit: "poires")

Ici, on déclare la fonction vendre() qui accepte un paramètre : la variable (ou plutôt la constante) fruit de type String. Le code qu’exécute la fonction est exactement le même qu’auparavant en remplaçant l’index “pommes” par la valeur de la constante fruit passée en paramètre dans func vendre(fruit:String). On peut exécuter la fonction en l’appelant plus loin dans le code en changeant simplement la valeur du paramètre.

On peut déclarer plusieurs paramètres pour chaque fonction en les séparant par des virgules :

1
func vendre(fruit: String, legume: String)

La compilation des fonctions

Toutes les constantes déclarées dans la fonction doivent être présentes lors de l’appel ou bien Xcode retournera une erreur de compilation. Le code qui est exécuté dans les fonctions l’est de manière synchrone ce qui veut dire que le code écrit après l’appel de la fonction ne sera exécuté que lorsque la totalité du code la fonction se sera exécuté.

1
2
3
print(argent)   // 10
vendre(fruit: "pommes")
print(argent)   // 12

Les fonctions peuvent agir sur les variables externes et les modifier pour la totalité du reste du script. Il est même possible de déclarer les fonctions avant les variables qu’elles utilisent :

1
2
3
4
5
6
func vendre(fruit:String) {
    // code
}

var argent = 10
vendre(fruit: "pommes")

Il est en revanche impossible d’utiliser une fonction avant sa déclaration dans un code procédural, c’est à dire en dehors des classes en programmation orientée objet, ce à quoi nous viendrons plus tard.

Pour des raisons pratiques, il est possible de donner deux noms différents pour un même paramètre passé, un pour l’appel, et l’autre pour l’intérieur de la fonction. Les deux noms seront donc déclarés l’un après l’autre dans la fonction, le nom extérieur en premier. Par exemple on pourrait déclarer func vendre(nomExterieur nomInterieur:String) ; pour appeler cette fonction on utiliserai vendre(nomExterieur: "scoubidous"), mais la variable contenant “scoubidous” à l’intérieur de la fonction s’appellera nomInterieur. On peut ainsi éviter d’avoir à entrer le nom de la variable dans l’appel de la fonction, en le remplaçant par un underscore (_) qui signifie “pas de nom de variable” en swift.

1
2
3
4
5
func vendre(_ fruit:String) {
    // code
}

vendre("pommes")

Les valeurs de retour

Une fonction peut retourner une valeur, qui sera alors stockée dans une variable. Il est nécessaire de définir le type de valeur qui sera retourné dans la déclaration de la fonction de cette façon :

1
2
3
4
5
func vendre(_ fruit:String) -> Bool {
    return true
}

var vendu = vendre("pommes") // true

Ici, on déclare avec -> Bool que la fonction retrournera une valeur de type boolean. Dans la fonction, on retourne ensuite la valeur souhaitée : true qui est ensuite stockée dans la variable “vendu”. Le code return permet d’effectuer le retour d’une valeur mais stoppe aussi l’exécution de la fonction. Aucun code ne pourra être exécuté après le return dans la fonction. Et puisque l’on a indiqué que la fonction retrournait une valeur, le return est obligatoire.

Par exemple, si on reprend le code pour la vente de tout à l’heure et que l’on souhaite y ajouter un retour indiquant si la vente s’est bien effectué, il faudra que le code exécute obligatoirement un return.

1
2
3
4
5
6
7
8
9
10
11
12
func vendre(fruit:String) -> Bool {
    if let stock = stockFruits[fruit] {
        if stock > 0 {
            if let prixAPayer = prix[fruit] {
                argent += prixAPayer
                stockFruits[fruit] = stock + 1
                return true
            }
        }
    }
    return false
}

On place un return false à la fin de la fonction car si elle s’exécute jusque là, c’est qu’elle ne s’est pas arrêté au return true et donc que fatalement, la vente n’a pas eu lieu. Il faut donc toujours penser à retourner une valeur par défaut si la fonctions contient plusieurs sorties (des return) différentes.

 

Bien ! Je crois qu’on a toutes les bases pour commencer à s’amuser un peu ! Si vous avez tout compris à ce chapitre vous pouvez être fier de vous car maintenant vous êtes capables de créer des programmes simples ! Et nous en ferons bientôt un …

Fin du tutoriel Commencer avec Swift


Exercice sur le cours

Exercice : Devine le nombre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *