Hur du returnerar flera värden från en Delphi-funktion

En vanligaste konstruktion i en Delphi-applikation är en procedur eller en funktion. Känd som rutiner, procedurer eller funktioner är uttalande block du ringer från olika platser i ett program.

Enkelt uttryckt är att en procedur är en rutin som inte returnerar ett värde medan en funktion returnerar ett värde.

Ett returvärde från en funktion definieras av returtypen. I de flesta fall skulle du skriva en funktion till returnera ett enda värde det skulle vara ett heltal, sträng, booleska eller någon annan enkel typ, även returtyper kan vara en matris, en stränglista, en instans av ett anpassat objekt eller lika.

Observera att även om din funktion returnerar en stränglista (en samling av strängar) returnerar den fortfarande ett enda värde: en instans av stränglistan.

Vidare kan Delphi-rutiner verkligen ha många ansikten: rutin, metod, metodpekare, händelsedelegat, anonym metod ...

Kan en funktion returnera flera värden?

Det första svaret som kommer till minnet är nej, helt enkelt för att när vi tänker på en funktion, tänker vi på ett enda avkastningsvärde.

Visst är svaret på ovanstående fråga dock ja. En funktion kan returnera flera värden. Låt oss se hur.

Var Parametrar

Hur många värden kan följande funktion returnera, en eller två?

fungera PositiveReciprocal (const värdeIn: heltal; var valueOut: real): boolean;

Funktionen returnerar uppenbarligen ett booleskt värde (sant eller falskt). Vad sägs om den andra parametern "valueOut" som deklarerats som en "VAR" (variabel) -parameter?

Var parametrar överförs till funktionen genom hänvisning vilket betyder att om funktionen ändrar värdet på parametern - en variabel i kodens blockblock - kommer funktionen att ändra värdet på den variabel som används för parametern.

För att se hur ovanstående fungerar, här är implementeringen:

fungera PositiveReciprocal (const värdeIn: heltal; var valueOut: real): boolean;

Börja

 resultat: = värdeIn> 0;

 om resultat sedan värdeOut: = 1 / värdeIn;

slutet;

"ValueIn" skickas eftersom en konstant parameterfunktion inte kan ändra den, och den behandlas som skrivskyddad.

Om "valueIn" eller större än noll tilldelas parametern "valueOut" det ömsesidiga värdet för "valueIn" och resultatet av funktionen är sant. Om värdeIn är <= 0 then the function returns false and "valueOut" is not altered in any way.

Här är användningen:

var

 b: booleska;

 r: verklig;

Börja

 r: = 5;

 b: = PositiveReciprocal (1, r);

 //här:

 // b = sant (sedan 1> = 0)

 // r = 0,2 (1/5)

 r: = 5;

 b: = PositiveReciprocal (-1, r);

 //här:

 // b = falsk (sedan -1 

slutet;

Därför kan PositiveReciprocal faktiskt "returnera" 2 värden! Med hjälp av var-parametrar kan du ha mer än ett värde rutinmässigt.

Ut parametrar

Det finns ett annat sätt att specificera en parameter för bifogad referens med hjälp av "ut" -sökordet, som i:

fungera PositiveReciprocalOut (const värdeIn: heltal; ut valueOut: real): boolean;

Börja

 resultat: = värdeIn> 0;

 om resultat sedan värdeOut: = 1 / värdeIn;

slutet;

Implementeringen av PositiveReciprocalOut är densamma som i PositiveReciprocal, det finns bara en skillnad: "valueOut" är en OUT-parameter.

Med parametrar som deklarerats som "ut" kastas det initiala värdet för den refererade variabeln "valueOut".

Här är användningen och resultaten:

var

 b: booleska;

 r: verklig;

Börja

 r: = 5;

 b: = PositiveReciprocalOut (1, r);

 //här:

 // b = sant (sedan 1> = 0)

 // r = 0,2 (1/5)

 r: = 5;

 b: = PositiveReciprocalOut (-1, r);

 //här:

 // b = falsk (sedan -1 

slutet;

Notera hur i det andra samtalet värdet på den lokala variabeln "r" är inställt på "0". Värdet på "r" ställdes till 5 före funktionssamtalet men eftersom parametern i deklarerats som "ut", när "r" nådde funktionen kasserades värdet och standard "tomt" värde inställdes för parametern (0 för riktig typ).

Som ett resultat kan du säkert skicka oinitialiserade variabler för utparametrar - något du inte ska göra med "var" -parametrar. Parametrar används för att skicka något till rutinen, utom här med "ut" -parametrar :), och därför kan oinitialiserade variabler (används för VAR-parametrar) ha konstiga värden.

Återvändande poster?

Ovanstående implementeringar där en funktion skulle returnera mer än ett värde är inte trevligt. Funktionen returnerar faktiskt ett enda värde, men returnerar också, bättre att säga ändrar, värdena på parametrarna var / out.

På grund av detta kan du mycket sällan använda parametrar för referens. Om fler resultat från en funktion krävs, kan du låta en funktion returnera en variabel av posttyp.

Tänk på följande:

typ

 TLatitudeLongitude = spela in

 Latitud: verklig;

 Longitud: verklig;

 slutet;

och en hypotetisk funktion:

fungera Var är jag(const townName: sträng): TLatitudeLongitude;

Funktionen WhereAmI skulle returnera Latitude och Longitud för en given stad (stad, område, ...).

Implementeringen skulle vara:

fungera Var är jag(const townName: sträng): TLatitudeLongitude;

Börja// använd någon tjänst för att hitta "townName" och tilldela sedan funktionsresultat:

 resultat.Latitude: = 45,54;

 resultat.Längd: = 18,71;

slutet;

Och här har vi en funktion som returnerar 2 verkliga värden. Okej, det returnerar en post, men den här posten har 2 fält. Observera att du kan ha en mycket komplex post som blandar olika typer som ska returneras till följd av en funktion.

Det är allt. Därför ja, Delphi-funktioner kan returnera flera värden.