Ein häufigstes Konstrukt in einer Delphi-Anwendung wäre eine Prozedur oder eine Funktion. Als Routinen, Prozeduren oder Funktionen bezeichnet man Anweisungsblöcke, die Sie an verschiedenen Stellen in einem Programm aufrufen.
Einfach ausgedrückt ist eine Prozedur eine Routine, die keinen Wert zurückgibt, während eine Funktion einen Wert zurückgibt.
Ein Rückgabewert von einer Funktion wird durch den Rückgabetyp definiert. In den meisten Fällen würden Sie eine Funktion schreiben einen einzelnen Wert zurückgeben Dies wäre eine Ganzzahl, eine Zeichenfolge, ein Boolescher Wert oder ein anderer einfacher Typ. Rückgabetypen können auch ein Array, eine Zeichenfolgenliste, eine Instanz eines benutzerdefinierten Objekts oder ähnliches sein.
Beachten Sie, dass Ihre Funktion auch dann einen einzelnen Wert zurückgibt, wenn sie eine Zeichenfolgenliste (eine Sammlung von Zeichenfolgen) zurückgibt: eine Instanz der Zeichenfolgenliste.
Außerdem können Delphi-Routinen wirklich viele Gesichter haben: Routine, Methode, Methodenzeiger, Ereignisdelegierter, anonyme Methode ...
Die erste Antwort, die mir einfällt, ist nein, einfach weil wir bei einer Funktion an einen einzelnen Rückgabewert denken.
Die Antwort auf die obige Frage lautet allerdings ja. Eine Funktion kann mehrere Werte zurückgeben. Mal sehen wie.
Wie viele Werte kann die folgende Funktion zurückgeben, einen oder zwei?
Funktion PositiveReciprocal (const valueIn: integer; var valueOut: real): boolean;
Die Funktion gibt offensichtlich einen booleschen Wert zurück (wahr oder falsch). Wie wäre es mit dem zweiten Parameter "valueOut", der als "VAR" -Parameter (Variable) deklariert ist?
Var-Parameter werden an die Funktion übergeben durch Bezugnahme Das heißt, wenn die Funktion den Wert des Parameters ändert - eine Variable im aufrufenden Codeblock -, ändert die Funktion den Wert der Variablen, die für den Parameter verwendet wird.
Um zu sehen, wie das oben genannte funktioniert, ist hier die Implementierung:
Funktion PositiveReciprocal (const valueIn: integer; var valueOut: real): boolean;
Start
Ergebnis: = valueIn> 0;
wenn Ergebnis dann valueOut: = 1 / valueIn;
Ende;
Das "valueIn" wird übergeben, da eine konstante Parameterfunktion es nicht ändern kann, und es wird als schreibgeschützt behandelt.
Wenn "valueIn" oder größer als Null, wird dem Parameter "valueOut" der Kehrwert von "valueIn" zugewiesen, und das Ergebnis der Funktion ist wahr. Wenn valueIn ist <= 0 then the function returns false and "valueOut" is not altered in any way.
Hier ist die Verwendung:
var
b: Boolescher Wert;
r: real;
Start
r: = 5;
b: = PositiveReciprocal (1, r);
//Hier:
// b = true (seit 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocal (-1, r);
//Hier:
// b = false (seit -1
Ende;
Daher kann der PositiveReciprocal tatsächlich 2 Werte "zurückgeben"! Mit var-Parametern kann eine Routine mehr als einen Wert zurückgeben.
Es gibt eine andere Möglichkeit, einen By-Reference-Parameter mit dem Schlüsselwort "out" wie folgt anzugeben:
Funktion PositiveReciprocalOut (const valueIn: integer; aus valueOut: real): boolean;
Start
Ergebnis: = valueIn> 0;
wenn Ergebnis dann valueOut: = 1 / valueIn;
Ende;
Die Implementierung von PositiveReciprocalOut ist dieselbe wie bei PositiveReciprocal, es gibt nur einen Unterschied: "valueOut" ist ein OUT-Parameter.
Bei Parametern, die als "out" deklariert sind, wird der Anfangswert der referenzierten Variablen "valueOut" verworfen.
Hier ist die Verwendung und die Ergebnisse:
var
b: Boolescher Wert;
r: real;
Start
r: = 5;
b: = PositiveReciprocalOut (1, r);
//Hier:
// b = true (seit 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocalOut (-1, r);
//Hier:
// b = false (seit -1
Ende;
Beachten Sie, wie beim zweiten Aufruf der Wert der lokalen Variablen "r" auf "0" gesetzt wird. Der Wert von "r" wurde vor dem Funktionsaufruf auf 5 gesetzt, aber da der Parameter als "out" deklariert wurde, wurde der Wert verworfen, als "r" die Funktion erreichte, und der Standardwert "empty" wurde für den Parameter (0) gesetzt für echten Typ).
Infolgedessen können Sie uninitialisierte Variablen sicher für Out-Parameter senden. Dies sollten Sie nicht mit "var" -Parametern tun. Parameter werden verwendet, um etwas an die Routine zu senden, außer hier mit "out" -Parametern :), und daher können nicht initialisierte Variablen (die für VAR-Parameter verwendet werden) seltsame Werte haben.
Die obigen Implementierungen, bei denen eine Funktion mehr als einen Wert zurückgeben würde, sind nicht schön. Die Funktion gibt tatsächlich einen einzelnen Wert zurück, gibt aber auch, besser gesagt, die Werte der var / out-Parameter zurück.
Aus diesem Grund möchten Sie möglicherweise sehr selten By-Reference-Parameter verwenden. Wenn weitere Ergebnisse einer Funktion erforderlich sind, kann eine Funktion eine Datensatztypvariable zurückgeben.
Folgendes berücksichtigen:
Art
TLatitudeLongitude = Aufzeichnung
Breite: echt;
Längengrad: real;
Ende;
und eine hypothetische Funktion:
Funktion Wo bin ich(const Ortsname: Zeichenfolge): TLatitudeLongitude;
Die Funktion WhereAmI würde die Breiten- und Längengrade für eine bestimmte Stadt (Stadt, Gebiet,…) zurückgeben..
Die Implementierung wäre:
Funktion Wo bin ich(const Ortsname: Zeichenfolge): TLatitudeLongitude;
Start// Verwenden Sie einen Dienst, um "townName" zu finden, und weisen Sie dann das Funktionsergebnis zu:
result.Latitude: = 45.54;
result.Longitude: = 18.71;
Ende;
Und hier haben wir eine Funktion, die 2 reelle Werte zurückgibt. Ok, es wird 1 Datensatz zurückgegeben, dieser Datensatz enthält jedoch 2 Felder. Beachten Sie, dass Sie einen sehr komplexen Datensatz haben können, der verschiedene Typen mischt, die als Ergebnis einer Funktion zurückgegeben werden sollen.
Das ist es. Daher können Delphi-Funktionen mehrere Werte zurückgeben.