Swift-7-

Fonction

Dans la plupart des langages de programmation on peut regrouper un ensemble d’instructions représentant une fonctionnalité particulière, sous le terme Fonction, Procédure ou Prédicat.

Une fonction est définie par le mot réservé func suivi par le nom de le fonction lui même suivi d’une double parenthèse à l’intérieur desquelles on déclare les paramètres ou arguments de la fonction. Le corps de la fonction dans lequel se placent les instructions est marqué par une accolade ouvrante et fermante. La fonction ci-dessous a pour nom AffficherHello, elle n’a pas de paramètres et le corps ne comporte qu’une seule instruction print

// Définition  
func AfficherHello() {
    print ("Hello")
}
// Utilisation
AfficherHello()
Paramètres

Une fonction peut comporter un ou plusieurs paramètres ou arguments ce qui permet de passer des valeurs dans le corps de la fonction, c’est le cas de tous les langages connus. Les paramètres sont écrits entre parenthèses () avec un nom de variable et son type. On peut spécifier un ou plusieurs paramètres séparés par une virgule. Une particularité de Swift oblige à ne pas spécifier le nom du premier paramètre lors de l’appel de la fonction, celui-ci faisant partie du nom de la fonction.

// Définition
func Afficher(message: String) {
print(message)
}
// Utilisation
let msg = " Hello"
Afficher(msg)
Afficher(message: msg) // produit une erreur à la compilation

//Définition d'une fonction avec plusieurs paramètres
func Afficher(message : String, nom : String) {
let texte = "\(nom), voici le message: \(message)"
print (texte)
}
//Utilisation
Afficher( "Bon voyage", nom: " Steve") 
Code Retour

Il est souvent nécessaire de demander à la fonction appelée de retourner une ou plusieurs valeurs , on utilise le mot réservé du langage return. On spécifie le type de code retour lors de la définition de la fonction avec le symbole ->

// Définition
func Afficher(message: String, nom: String) -> String {
    let réponse = "\(nom), voici le message \(message)"
    return réponse
}
// Utilisation
let réponse = Afficher( "Bon voyage", nom: " Steve")
print(réponse)

Une fonction peut renvoyer plusieurs code retour au moyen d’un Tuple

// Définition
func myContact() -> (String, String) {
   return ("Steve", "Jobs")
}
// Utilisation
let contact = myContact()
print(contact.0,contact.1)
print(myContact().0)
print(myContact().1)
print(" \(myContact().0) \(myContact().1)")
print(myContact())

 

Paramètre local et externe
func Afficher(message: String) {
    println(message)
}

Le nom d’un paramètre est uniquement utilisé à l’intérieur du corps de la fonction mais pas à l’extérieur lors de l’appel de la fonction. Comme précisé précédemment, seul le nom du premier paramètre n’est pa mentionné lors de l’appel de la fonction.
Il est cependant intéressant, lorsque la fonction accepte plusieurs paramètres de vouloir déterminer quelle valeur correspond à quel paramètre. Ainsi lors d’une fonction de calcul de puissance on peut supposer en fonction de l’ordre des paramètre que l’on veut élever 4 à la puissance 3

let resultat = Puissance(4,3)

Pour éviter toute confusion Swift offre le moyen de préciser ou non un paramètre de fonction pour qu’il soit reconnu à l’extérieur de la fonction. la fonction Puissance pourrait donc se définir de la façon suivante. On remarque que le nom externe est séparé du nom interne par un espace.

func Puissance(nombre  n : Int, exposant e: Int)  -> Int  {
   var résultat = n 
   for  _ in 1..< e {
      résultat = résultat * n 
   }
   return résultat
}

Lors de l’appel de cette fonction nous écrirons

Puissance( nombre: 4, exposant: 3)

Ce qui permet de reconnaitre sans ambiguïté le rôle de chaque paramètre.

Il peut arriver que l’on veuille utiliser le même nom pour un paramètre externe et interne, dans ce cas il de doubler le nom du premier paramètre uniquement

func Puissance(nombre nombre : Int, exposant : Int)  -> Int  {
   var résultat = nombre 
   for  _ in 1..< exposant {
      résultat = résultat * nombre 
   }
   return résultat
}

Un point important: la déclaration d’un nom externe pour une paramètre de fonction implique l’obligation d’utiliser ce nom dans l’appel de la fonction.

Lors de l’appel d’un fonction, il est possible d’omettre le nom des paramètres en plaçant un _ (underscore) devant le nom du paramètre.

func Afficher (hello : String, _ contact : String)   {
   print( "\(hello) \(contact) ")
}
Afficher("hello" , "Steve")
Valeur par défaut

Il est possible de déclarer des valeurs par défaut pour lea paramètres d’une fonction

func Afficher (hello : String = "Bonjour", contact : String)   {
    print( " \hello \contact")
}

Dans le cas ou un paramètre a une valeur par défaut Swift déclare un nom de paramètre externe identique au nom de paramètre interne. dans l’exemple précédent « hello » est aussi un nom externe.

let message = Afficher( hello, contact: "John")

Bien que cet approche présente des avantages, il est malgré tout possible de désactiver ce mécanisme en plaçant un _ devant le paramètre externe par le symbole _ ( underscore)

func Afficher( _hello  hello : String = "Hi"
             , contact : String
             , _bye aurevoir: String = "How are you doing") {
    print( "\(hello) \(contact) \(aurevoir)")
}
Afficher(contact: "John")

 

Paramètres multiples

un paramètre dit « variadic » selon la terminologie employée dans la documentation Swift de Apple est un paramètre qui peut accepter un nombre de valeurs non déterminé lors de la définition de la fonction. Les valeurs d’un paramètre « variadic » doivent être de même type.

func énumération (nombre : Int …) {
   for n in nombre {
     print( " les nombres \n ")
   }
}
énumération(1,5,6)
Note
    1- Un paramètre variadic doit se trouver en dernière position dans la liste de paramètres
    2- Une fonction ne peut avoir qu'un seul paramètre variadic dans la liste de paramètres
Paramètre & mutabilité

La valeur d’un paramètre est dit mutable s’il est susceptible d’être modifié dans le corps de la fonction. Par défaut les valeurs des paramètres d’une fonction sont des « constantes » donc non modifiable. Si l’on veut changer la valeur d’un paramètre à l’intérieur de la fonction, il faut faire précéder le paramètre par le mot réservé var. Swift va alors créer une copie du paramètre qui pourra donc être modifié dans la fonction.
Cependant cela ne veut pas dire que l’un peut passer un paramètre, en changer la valeur dans le fonction et utiliser cette valeur modifiée en retour de la fonction car la fonction n’utilise la valeur du paramètre modifié que pendant le temps de traitement à l’intérieur de la fonction.

In out paramètre

Comme précisé dans le paragraphe précédent, la valeur d’un paramètre est une constante non modifiable. Si l’on veut apporter un changement à la valeur de paramètre dans le corps de la fonction et le rendre visible à l’extérieur de la fonction il faut qualifier ce paramètre avec le mot réservé du langage inout. Dans ce cas le type de la valeur du paramètre doit être une variable déclarée avec le mot réservé var et non let

Remarques:

Lors de l’appel d’un fonction comportant un paramètre inout, il faut faire précéder chaque variable par le symbole pour indiquer que cette variable peut être modifiée en retour de la fonction. Un paramètre inout ne peut avoir de valeur par défaut La notation d’un paramètre à la fois var et inout est incompatible. La déclaration inout d’un paramètre est un autre moyen que return de retourner des valeurs lors d’un appel de fonction

Une fonction dans une fonction

Une fonction peut contenir d’autres fonctions dites « intégrées ». La particularité est qu’un fonction intégrée accéder aux valeurs des variables de la fonction englobante.

func MessageAugmenté(message: String) {
   func AfficherPlus(message:String) {
      print("------------------")
      print(message)
      print("------------------")
   }
 }
MessageAugmenté("You are welcome Steve")

 

Fonction en paramètre d’une autre fonction
func AfficherPlus(message: String) {
   print("------------------")
   print(message)
   print("------------------")
}
func Message(message: String, afficher: (String) -> ()) { 
   afficher(message) 
} 

Appel de la fonction Message avec la fonction AfficherPlus en paramètre

Message("Hello John", afficher: AfficherPlus)

Un exemple de fonctions enchainées

func  DisplayMessage(message: String) -> String -> String -> String {
    func texteDebut(unTexte: String) -> String -> String {
        func texteFin(texte : String) -> String {
            return ("\(texte) \(unTexte) \(message)")
          }
        return texteFin
    }
    return texteDebut
}

Appel de la fonction

print((DisplayMessage ("debut")("milieu")(" fin")))

Notez que pour préciser que le type de retour de la fonction « contenante » et une fonction qui prend en paramètre une variable de type String et qui retourne à son tour une variable de type String, nous utilisons la notation : String -> String.