Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Swift
Code

Swift from Scratch: Paramètres de fonction, types et imbrication

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Swift From Scratch.
Swift From Scratch: An Introduction to Functions
Swift From Scratch: Closures

French (Français) translation by Ahmad Fauzan (you can also view the original English article)

Dans l'article précédent, nous avons exploré les bases des fonctions dans Swift. Les fonctions ont cependant beaucoup plus à offrir. Dans cet article, nous allons poursuivre notre exploration des fonctions et examiner leurs paramètres, leur imbrication et leurs types.

1. Noms des paramètres locaux et externes

Noms de paramètres locaux

Revenons sur l'un des exemples de l'article précédent. La fonction printMessage définit un paramètre, message.

Même si nous donnons un nom au paramètre, un message, nous ne l'utilisons pas lorsque nous appelons la fonction. Nous passons dans la valeur pour le paramètre de message.

Le nom que nous définissons dans la définition de la fonction est un nom de paramètre local. La valeur du paramètre ne peut être référencée que par ce nom dans le corps de la fonction. Les paramètres de fonction, cependant, sont un peu plus flexibles que cela. Laissez-moi expliquer ce que je veux dire par là.

Objective-C est connu pour ses noms de méthode longs. Bien que cela puisse paraître maladroit et inélégant aux étrangers, cela rend les méthodes faciles à comprendre et, si bien choisies, très descriptives. Si vous pensez avoir perdu cet avantage lors du passage à Swift, vous serez surpris.

Noms de paramètres externes

Lorsqu'une fonction accepte plusieurs paramètres, il n'est pas toujours évident de savoir quel argument correspond à quel paramètre. Regardez l'exemple suivant pour mieux comprendre le problème.

La fonction de puissance augmente la valeur de a par l'exposant b. Les deux paramètres sont de type Int. Bien que la plupart des gens passent intuitivement la valeur de base comme premier argument et l’exposant comme second argument, cela n’est pas clair pour le type, le nom ou la signature de la fonction. Comme nous l'avons vu dans l'article précédent, invoquer la fonction est simple.

Pour éviter toute confusion, nous pouvons donner les paramètres d'une fonction à des noms externes. Nous pouvons ensuite utiliser ces noms externes lorsque la fonction est appelée pour indiquer sans ambiguïté quel argument correspond à quel paramètre. Jetez un coup d'œil à l'exemple mis à jour ci-dessous.

Notez que le corps de la fonction n'a pas changé depuis les noms locaux. Cependant, lorsque nous appelons la fonction mise à jour, la différence est nette et le résultat beaucoup moins déroutant.

Bien que les types des deux fonctions soient les mêmes (Int, Int) -> Int, les fonctions sont différentes. En d'autres termes, la deuxième fonction n'est pas une redéclaration de la première fonction. La syntaxe d'invocation de la deuxième fonction peut vous rappeler Objective-C. Non seulement les arguments sont clairement décrits, mais la combinaison des noms de fonction et de paramètre décrit le but de la fonction.

Dans certains cas, vous souhaitez utiliser les mêmes noms pour les noms de paramètres locaux et externes. C'est possible et il n'est pas nécessaire de saisir le nom du paramètre deux fois. Dans l'exemple suivant, nous utilisons base et exposant comme noms de paramètres locaux et externes.

En faisant précéder le nom du paramètre avec le symbole #, le nom du paramètre est le nom local et externe du paramètre. Cela signifie également que nous devons mettre à jour le corps de la fonction.

Il est important de noter qu'en fournissant un nom externe à un paramètre, vous devez utiliser ce nom pour appeler la fonction. Cela nous amène aux valeurs par défaut.

Les valeurs par défaut

Nous avons abordé les valeurs de paramètre par défaut dans l'article précédent, mais vous devez être conscient du comportement par défaut important. Si vous définissez une valeur par défaut pour un paramètre, Swift attribue automatiquement un nom de paramètre externe au paramètre. Regardons un exemple de l'article précédent.

Le second paramètre, format, ayant une valeur par défaut, Swift définit automatiquement le nom du paramètre externe du formatformater. En d’autres termes, le résultat est le même, comme si nous étions au préfixe de format avec le symbole #. Vous pouvez tester cela en invoquant la fonction ci-dessus dans votre terrain de jeu. Que se passe-t-il si vous passez dans le format sans utiliser le nom de paramètre externe du second paramètre? La réponse est indiquée ci-dessous.

Swift est assez clair sur ce que nous devrions faire. En résumé, lorsque vous définissez un paramètre comme facultatif, Swift définit automatiquement le nom du paramètre externe sur le nom du paramètre local. L'idée derrière ce comportement est d'éviter la confusion et l'ambiguïté.

Bien que ce comportement soit une bonne pratique recommandée, il est possible de le désactiver. Dans la définition de fonction mise à jour ci-dessous, nous ajoutons un trait de soulignement auquel nous ajouterions normalement le nom du paramètre externe. Cela indique à Swift que nous ne souhaitons pas définir un nom de paramètre externe pour ce paramètre particulier, malgré le fait qu’il possède une valeur par défaut.

Nous pouvons maintenant appeler la fonction formatDate sans fournir de nom pour le second argument.

2. Paramètres et mutabilité

Revenons au premier exemple de ce didacticiel, la fonction printMessage. Que se passe-t-il si nous modifions la valeur du paramètre message dans le corps de la fonction?

Swift ne tarde pas à se plaindre.

Par défaut, les paramètres d'une fonction sont des constantes. En d'autres termes, bien que nous puissions accéder aux valeurs des paramètres de fonction, nous ne pouvons pas modifier leur valeur. Pour modifier ce comportement par défaut, ajoutez le mot clé var au nom du paramètre dans la définition de la fonction. Swift créera alors une copie variable de la valeur du paramètre à utiliser dans le corps de la fonction.

Notez que cela ne signifie pas que vous pouvez transmettre une valeur, la modifier dans la fonction et utiliser la valeur modifiée une fois que la fonction a fonctionné. Swift crée une copie de la valeur du paramètre qui n'existe que pour la durée de vie de l'appel de fonction. Ceci est également illustré dans le bloc de code suivant dans lequel nous passons une constante à la fonction printMessage.

3. Paramètres variadiques

Bien que le terme puisse sembler étrange au début, les paramètres variadiques sont courants en programmation. Un paramètre variadique est un paramètre qui accepte zéro ou plusieurs valeurs. Les valeurs doivent être du même type. L'utilisation de paramètres variadiques dans Swift est simple, comme l'illustre l'exemple suivant.

La syntaxe est facile à comprendre. Pour marquer un paramètre comme variable, vous ajoutez trois points au type du paramètre. Dans le corps de la fonction, le paramètre variadic est accessible sous forme de tableau. Dans l'exemple ci-dessus, args est un tableau de valeurs Int.

Comme Swift a besoin de savoir quels arguments correspondent à quels paramètres, un paramètre variadique doit être le dernier paramètre. Cela implique également qu'une fonction peut avoir au plus un paramètre variadique.

Ce qui précède s'applique également si une fonction a des paramètres avec des valeurs par défaut. Le paramètre variadic devrait toujours être le dernier paramètre.

4. Paramètres In-Out

Plus tôt dans ce didacticiel, vous avez appris à définir la mutabilité d'un paramètre à l'aide du mot clé var. Dans cette section, j'ai souligné que la valeur d'un paramètre de variable n'est accessible que depuis le corps de la fonction. Si vous souhaitez transmettre une valeur à une fonction, la modifier dans la fonction et la renvoyer hors de la fonction, les paramètres in-out sont ce que vous recherchez.

L'exemple suivant montre un exemple d'utilisation des paramètres d'entrée-sortie dans Swift et de la syntaxe

Nous avons défini le premier paramètre en tant que paramètre in-out en ajoutant le mot clé inout. Le second paramètre est un paramètre standard avec un nom externe, withString, et un nom local, b. Voyons comment nous appelons cette fonction.

Nous déclarons une variable, world, de type String et la passons à la fonction perpendString. Le deuxième paramètre est un littéral de chaîne. En appelant la fonction, la valeur de la variable world devient Hello, world. Notez que le premier argument est préfixé par une esperluette, &, pour indiquer qu'il s'agit d'un paramètre in-out.

Il va sans dire que les constantes et les littéraux ne peuvent pas être passés en tant que paramètres in-out. Swift génère une erreur lorsque vous procédez comme illustré dans la capture d'écran suivante.

Il est évident que les paramètres in-out ne peuvent pas avoir de valeurs par défaut, être variadiques ou définis comme var ou let. Si vous oubliez ces informations, Swift vous le rappellera avec une erreur.

5. Nidification

En C et Objective-C, les fonctions et méthodes ne peuvent pas être imbriquées. Dans Swift, cependant, les fonctions imbriquées sont assez courantes. Les fonctions décrites dans cet article et dans l'article précédent sont des exemples de fonctions globales. Elles sont définies dans la portée globale.

Lorsque nous définissons une fonction dans une fonction globale, nous appelons cette fonction une fonction imbriquée. Une fonction imbriquée a accès aux valeurs définies dans sa fonction englobante. Regardez l'exemple suivant pour mieux comprendre cela.

Bien que les fonctions de cet exemple ne soient pas très utiles, l'exemple illustre l'idée de fonctions imbriquées et de capture de valeurs. La fonction printHelloWorld est uniquement accessible depuis la fonction printMessage. Comme illustré dans l'exemple, la fonction printHelloWorld a accès à la constante a. La valeur est capturée par la fonction imbriquée et est donc accessible à partir de cette fonction. Swift prend en charge la capture des valeurs, y compris la gestion de la mémoire de ces valeurs.

6. Types de fonction

Dans l'article précédent, nous avons brièvement abordé les types de fonctions. Une fonction a un type particulier, composé des types de paramètre de la fonction et de son type de retour. La fonction printMessage, par exemple, est de type (String)-> (). Rappelez-vous que () symbolise le vide, ce qui équivaut à un tuple vide.

Chaque fonction ayant un type, il est possible de définir une fonction qui accepte une autre fonction en tant que paramètre. L'exemple suivant montre comment cela fonctionne.

La fonction printMessageWithFunction accepte une chaîne comme premier paramètre et une fonction de type (String)-> () comme deuxième paramètre. Dans le corps de la fonction, la fonction que nous transmettons est appelée avec l'argument de message.

L'exemple montre également comment appeler la fonction printMessageWithFunction. La constante myMessage est transmise en tant que premier argument et la fonction printMessage, définie précédemment, en tant que second argument. À quel point cela est cool?

Comme je l'ai mentionné précédemment, il est également possible de renvoyer une fonction à partir d'une fonction. L'exemple suivant est un peu artificiel, mais il illustre à quoi ressemble la syntaxe.

La fonction de calcul accepte une valeur booléenne et retourne une fonction de type (Int, Int)-> int. La fonction de calcul contient deux fonctions imbriquées qui sont également de type (Int, Int)-> Int, additionner et soustraire.

La fonction compute renvoie une référence à la fonction add ou subtract, en fonction de la valeur du paramètre addition. L'exemple montre également comment utiliser la fonction de calcul. Nous stockons une référence à la fonction renvoyée par la fonction compute dans la constante computeFunction. Nous avons ensuite invoquer la fonction stockée dans computeFunction, en passant au magasin 1 et 2, le résultat au résultat et imprimer la valeur du résultat dans la sortie standard. L'exemple peut paraître complexe, mais il est en fait facile à comprendre si vous savez ce qui se passe.

Conclusion

Vous devez maintenant bien comprendre le fonctionnement des fonctions dans Swift et ce que vous pouvez en faire. Les fonctions sont un thème commun dans Swift et vous les utiliserez beaucoup lorsque vous travaillerez avec Swift.

Dans le prochain article, nous nous plongerons dans les fermetures, une construction puissante qui rappelle les blocs en C et Objective-C, les fermetures en JavaScript et les lambdas en Ruby.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.