Een meest voorkomende constructie in een Delphi-toepassing is een procedure of een functie. Bekend als routines, procedures of functies zijn instructieblokken die u vanuit verschillende locaties in een programma aanroept.
Simpel gezegd is een procedure een routine die geen waarde retourneert, terwijl een functie een waarde retourneert.
Een retourwaarde van een functie wordt bepaald door het retourtype. In de meeste gevallen schrijft u een functie naar retourneer een enkele waarde dat zou een geheel getal, string, boolean of een ander eenvoudig type zijn, ook retourtypen kunnen een array, een stringlijst, een exemplaar van een aangepast object of iets dergelijks zijn.
Merk op dat zelfs als uw functie een tekenreekslijst retourneert (een verzameling tekenreeksen) deze nog steeds een enkele waarde retourneert: één exemplaar van de tekenreekslijst.
Verder kunnen Delphi-routines echt veel gezichten hebben: Routine, Method, Method Pointer, Event Delegate, Anonieme methode ...
Het eerste antwoord dat te binnen schiet is nee, simpelweg omdat wanneer we aan een functie denken, we aan een enkele retourwaarde denken.
Zeker, het antwoord op bovenstaande vraag is echter ja. Een functie kan verschillende waarden retourneren. Laten we eens kijken hoe.
Hoeveel waarden kan de volgende functie retourneren, een of twee?
functie PositiveReciprocal (const valueIn: geheel getal; var valueOut: real): boolean;
De functie retourneert uiteraard een booleaanse waarde (waar of onwaar). Hoe zit het met de tweede parameter "valueOut" gedeclareerd als een "VAR" (variabele) parameter?
Var-parameters worden doorgegeven aan de functie door verwijzing wat betekent dat als de functie de waarde van de parameter verandert - een variabele in het aanroepende blok van code - de functie de waarde van de variabele verandert die wordt gebruikt voor de parameter.
Om te zien hoe het bovenstaande werkt, volgt hier de implementatie:
functie PositiveReciprocal (const valueIn: geheel getal; var valueOut: real): boolean;
beginnen
resultaat: = waardeIn> 0;
als resultaat vervolgens valueOut: = 1 / valueIn;
einde;
De "valueIn" wordt doorgegeven als een constante parameter-functie kan deze niet wijzigen en wordt als alleen-lezen behandeld.
Als "valueIn" of groter dan nul is, krijgt de parameter "valueOut" de wederzijdse waarde van "valueIn" toegewezen en is het resultaat van de functie waar. Als valueIn is <= 0 then the function returns false and "valueOut" is not altered in any way.
Dit is het gebruik:
var
b: boolean;
r: echt;
beginnen
r: = 5;
b: = PositiveReciprocal (1, r);
//hier:
// b = true (sinds 1> = 0)
// r = 0.2 (1/5)
r: = 5;
b: = PositiveReciprocal (-1, r);
//hier:
// b = false (sinds -1
einde;
Daarom kan de PositiveReciprocal 2 waarden "retourneren"! Met var-parameters kunt u meer dan één waarde routinematig retourneren.
Er is nog een manier om een referentieparameter op te geven met behulp van het trefwoord "out", zoals in:
functie PositiveReciprocalOut (const valueIn: geheel getal; uit valueOut: real): boolean;
beginnen
resultaat: = waardeIn> 0;
als resultaat vervolgens valueOut: = 1 / valueIn;
einde;
De implementatie van PositiveReciprocalOut is hetzelfde als in PositiveReciprocal, er is maar één verschil: de "valueOut" is een OUT-parameter.
Met parameters die als "uit" worden aangegeven, wordt de initiële waarde van de variabele "valueOut" verwijderd.
Hier is het gebruik en de resultaten:
var
b: boolean;
r: echt;
beginnen
r: = 5;
b: = PositiveReciprocalOut (1, r);
//hier:
// b = true (sinds 1> = 0)
// r = 0.2 (1/5)
r: = 5;
b: = PositiveReciprocalOut (-1, r);
//hier:
// b = false (sinds -1
einde;
Merk op hoe in de tweede aanroep de waarde van de lokale variabele "r" is ingesteld op "0". De waarde van "r" was ingesteld op 5 vóór de functieaanroep, maar omdat de parameter in "uit" werd verklaard, werd "waarde" genegeerd toen "r" de functie bereikte en werd de standaardwaarde "leeg" ingesteld voor de parameter (0 voor echt type).
Als gevolg hiervan kunt u veilig niet-geïnitialiseerde variabelen verzenden voor parameters - iets dat u niet moet doen met "var" -parameters. Parameters worden gebruikt om iets naar de routine te sturen, behalve hier met "uit" -parameters :), en daarom kunnen niet-geïnitialiseerde variabelen (gebruikt voor VAR-parameters) rare waarden hebben.
De bovenstaande implementaties waarbij een functie meer dan één waarde zou opleveren, zijn niet leuk. De functie retourneert eigenlijk een enkele waarde, maar retourneert ook, beter gezegd, de waarden van de var / out-parameters.
Daarom wilt u misschien zelden by-referentieparameters gebruiken. Als meer resultaten van een functie vereist zijn, kunt u een functie een record van het type record laten retourneren.
Stel je de volgende situatie voor:
type
TLatitudeLongitude = Vermelding
Breedtegraad: echt;
Lengtegraad: echt;
einde;
en een hypothetische functie:
functie Waar ben ik(const townName: draad): TLatitudeLongitude;
De functie WhereAmI retourneert de lengte- en breedtegraad voor een bepaalde stad (stad, gebied, ...).
De implementatie zou zijn:
functie Waar ben ik(const townName: draad): TLatitudeLongitude;
beginnen// gebruik een service om "townName" te vinden en wijs vervolgens het functieresultaat toe:
result.Latitude: = 45,54;
result.Longitude: = 18.71;
einde;
En hier hebben we een functie die 2 echte waarden retourneert. Ok, het retourneert 1 record, maar dit record heeft 2 velden. Merk op dat u een zeer complex record kunt hebben waarin verschillende typen worden gemixt om te worden geretourneerd als gevolg van een functie.
Dat is het. Daarom kunnen ja, Delphi-functies meerdere waarden retourneren.