En vanligaste konstruktion i en Delphi ansökan skulle vara 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) det returnerar 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 deklareras som en "VAR" -parameter?
Var parametrar överförs till funktionen genom hänvisning vilket innebär 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 som en konstant parameter - funktionen kan inte ä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 valueIn är <= 0, returnerar funktionen falskt och "valueOut" ändras inte på något sätt.
Här är användningen:
var
b: booleska;
r: verklig;
Börja
r: = 5;
b: = PositiveReciprocal (1, r);
//here:
// b = sant (sedan 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocal (-1, r);
//here:
// 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 ange en parameter för bifogad referens - med hjälp av sökordet "ut", 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);
//here:
// b = sant (sedan 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocalOut (-1, r);
//here:
// 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" sattes till 5 före funktionssamtalet, men eftersom parametern i deklareras som "ut", när "r" nådde funktionen värdet kasserades och standard "tomt" värde inställdes för parametern (0 för real 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 (som används för VAR-parametrar) ha konstiga värden.
Återvända 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 få en funktionsåtergång a inspelningstyp variabel.
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 Latitud och longitud för en viss 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. Latitud: = 45,54;
resultat. Longitud: = 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.