Une construction la plus courante dans une application Delphi serait une procédure ou une fonction. Les routines, procédures ou fonctions sont des blocs d'instructions que vous appelez depuis différents emplacements d'un programme.
Autrement dit, une procédure est une routine qui ne renvoie pas de valeur tandis qu'une fonction renvoie une valeur.
Une valeur de retour d'une fonction est définie par le type de retour. Dans la plupart des cas, vous écririez une fonction dans retourner une seule valeur qui serait un entier, une chaîne, un booléen ou un autre type simple, les types de retour pourraient également être un tableau, une liste de chaînes, une instance d'un objet personnalisé ou similaire.
Notez que même si votre fonction renvoie une liste de chaînes (une collection de chaînes), elle renvoie toujours une seule valeur: une instance de la liste de chaînes.
De plus, les routines Delphi peuvent vraiment avoir de nombreux visages: Routine, Méthode, Pointeur de méthode, Délégué d'événement, Méthode anonyme…
La première réponse qui vient à l'esprit est non, simplement parce que lorsque nous pensons à une fonction, nous pensons à une seule valeur de retour.
Certes, la réponse à la question ci-dessus est cependant oui. Une fonction peut renvoyer plusieurs valeurs. Voyons comment.
Combien de valeurs la fonction suivante peut-elle retourner, une ou deux?
une fonction PositiveReciprocal (const valueIn: entier; var valueOut: real): booléen;
La fonction renvoie évidemment une valeur booléenne (true ou false). Que diriez-vous du deuxième paramètre "valueOut" déclaré comme paramètre "VAR" (variable)?
Paramètres Var sont passés à la fonction par référence ce qui signifie que si la fonction change la valeur du paramètre - une variable dans le bloc de code appelant - la fonction changera la valeur de la variable utilisée pour le paramètre.
Pour voir comment cela fonctionne, voici l'implémentation:
une fonction PositiveReciprocal (const valueIn: entier; var valueOut: real): booléen;
commencer
résultat: = valeurIn> 0;
si résultat ensuite valueOut: = 1 / valueIn;
fin;
Le "valueIn" est passé car une fonction de paramètre constante ne peut pas le modifier, et il est traité en lecture seule.
Si "valueIn" ou supérieur à zéro, le paramètre "valueOut" reçoit la valeur réciproque de "valueIn" et le résultat de la fonction est vrai. Si valueIn est <= 0 then the function returns false and "valueOut" is not altered in any way.
Voici l'utilisation:
var
b: booléen;
r: réel;
commencer
r: = 5;
b: = PositiveReciprocal (1, r);
//ici:
// b = vrai (puisque 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocal (-1, r);
//ici:
// b = faux (depuis -1
fin;
Par conséquent, le PositiveReciprocal peut réellement "renvoyer" 2 valeurs! En utilisant les paramètres var, une routine peut renvoyer plusieurs valeurs.
Il existe une autre façon de spécifier un paramètre par référence en utilisant le mot clé "out", comme dans:
une fonction PositiveReciprocalOut (const valueIn: entier; en dehors valueOut: real): booléen;
commencer
résultat: = valeurIn> 0;
si résultat ensuite valueOut: = 1 / valueIn;
fin;
L'implémentation de PositiveReciprocalOut est la même que dans PositiveReciprocalOut, il n'y a qu'une seule différence: le "valueOut" est un paramètre OUT.
Avec les paramètres déclarés comme "out", la valeur initiale de la variable référencée "valueOut" est ignorée.
Voici l'utilisation et les résultats:
var
b: booléen;
r: réel;
commencer
r: = 5;
b: = PositiveReciprocalOut (1, r);
//ici:
// b = vrai (puisque 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocalOut (-1, r);
//ici:
// b = faux (depuis -1
fin;
Notez comment dans le deuxième appel la valeur de la variable locale "r" est définie sur "0". La valeur de "r" a été définie sur 5 avant l'appel de la fonction, mais comme le paramètre in a été déclaré comme "out", lorsque "r" a atteint la fonction, la valeur a été ignorée et la valeur "vide" par défaut a été définie pour le paramètre (0 pour le type réel).
Par conséquent, vous pouvez envoyer en toute sécurité des variables non initialisées pour les paramètres out, ce que vous ne devriez pas faire avec les paramètres "var". Les paramètres sont utilisés pour envoyer quelque chose à la routine, sauf ici avec les paramètres "out" :), et donc les variables non initialisées (utilisées pour les paramètres VAR) peuvent avoir des valeurs étranges.
Les implémentations ci-dessus où une fonction retournerait plus d'une valeur ne sont pas agréables. La fonction retourne en fait une seule valeur, mais retourne aussi, pour mieux dire altère, les valeurs des paramètres var / out.
Pour cette raison, vous souhaiterez très rarement utiliser des paramètres de référence. Si plus de résultats d'une fonction sont requis, vous pouvez demander à une fonction de renvoyer une variable de type d'enregistrement.
Considérer ce qui suit:
type
TLatitudeLongitude = record
Latitude: réelle;
Longitude: réel;
fin;
et une fonction hypothétique:
une fonction Où suis-je(const nom de la ville: chaîne): TLatitudeLongitude;
La fonction WhereAmI retournerait la latitude et la longitude pour une ville donnée (ville, région,…).
La mise en œuvre serait:
une fonction Où suis-je(const nom de la ville: chaîne): TLatitudeLongitude;
commencer// utilise un service pour localiser "townName", puis attribue le résultat de la fonction:
résultat.Latitude: = 45,54;
résultat.Longitude: = 18,71;
fin;
Et ici, nous avons une fonction renvoyant 2 valeurs réelles. Ok, il retourne 1 enregistrement, mais cet enregistrement a 2 champs. Notez que vous pouvez avoir un enregistrement très complexe mélangeant différents types à renvoyer à la suite d'une fonction.
C'est ça. Par conséquent, oui, les fonctions Delphi peuvent renvoyer plusieurs valeurs.