Meerdere waarden retourneren vanuit een Delphi-functie

Een meest voorkomende constructie in een Delphi applicatie zou een zijn 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 instantie van een aangepast object of iets dergelijks zijn.

Merk op dat zelfs als uw functie een stringlijst retourneert (een verzameling van snaren) het retourneert nog steeds een enkele waarde: één exemplaar van de stringlijst.

Verder kunnen Delphi-routines echt veel gezichten hebben: Routine, Methode, Method Pointer, Event Delegate, Anonieme methode ...

Kan een functie meerdere waarden retourneren?

instagram viewer

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.

Var-parameters

Hoeveel waarden kan de volgende functie retourneren, een of twee?

functie PositiefReciprocal (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 (een variabele in het aanroepende codeblok) wijzigt, de functie de waarde van de variabele verandert die voor de parameter wordt gebruikt.

Om te zien hoe het bovenstaande werkt, volgt hier de implementatie:

functie PositiefReciprocal (const valueIn: geheel getal; var valueOut: real): boolean;

beginnen

 resultaat: = waardeIn> 0;

als resultaat vervolgens valueOut: = 1 / valueIn;

einde;

De "waardeIn" 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 <= 0 is, retourneert de functie false en wordt "valueOut" op geen enkele manier gewijzigd.

Dit is het gebruik:

var

 b: boolean;

 r: echt;

beginnen

 r: = 5;

 b: = PositiveReciprocal (1, r);

 //here:

 // b = true (sinds 1> = 0)

 // r = 0.2 (1/5)

 r: = 5;

 b: = PositiveReciprocal (-1, r);

 //here:

 // b = false (sinds -1 

einde;

Daarom kan de PositiveReciprocal 2 waarden "retourneren"! Met var-parameters kunt u meer dan één waarde routinematig retourneren.

Parameters uit

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);

 //here:

 // b = true (sinds 1> = 0)

 // r = 0.2 (1/5)

 r: = 5;

 b: = PositiveReciprocalOut (-1, r);

 //here:

 // 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 aangezien de parameter wordt aangegeven als "uit", wanneer "r" de functie heeft bereikt, is de waarde weggegooid en is 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.

Records retourneren?

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 er meer resultaten van een functie vereist zijn, kunt u een functie retourneren a recordtype variabel.

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 zou de Breedtegraad en lengtegraad 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:

 resultaat. Breedtegraad: = 45,54;

 resultaat. Lengtegraad: = 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 die als resultaat van een functie moeten worden geretourneerd.

Dat is het. Daarom kunnen ja, Delphi-functies meerdere waarden retourneren.