![]() |
Function mit mehreren Rückgabewerten
Hallo Leute, heute habe ich mal wieder eine Frage:
Ich habe nun eine eigene function geschriebenm, inder ich aber mehrere Rückgabewerte bekomme. Jetzt ist die Frage, wie ich auf diese zugreifen kann, da ja Result nur einen Wert wiedergibt? Um es ein wenig zu vereinfachen hier ein kleines Beispiel (Nur gerade aus den kopf geschrieben)
Code:
Wie kann ich nun in einer anderen Function auf a und b zugreifen?
function MoreResults:string;
begin a := 1; b := 2; end; Wie gesagt, mit Result bekomme ich ja nur einen Wert zurück. Ich hoffe ihr könnt mir helfen |
AW: Function mit mehreren Rückgabewerten
Hallo,
Du könntest als Result ein Record verwenden. Grüße Klaus |
AW: Function mit mehreren Rückgabewerten
entweder du deklarierst einen Record
Delphi-Quellcode:
oder du übergibst der function Var-Parameter
type
TDeinRecord=record x:Integer; y:Integer; end;
Delphi-Quellcode:
Dabei musst du die variablen aus der aufrufenden funktion übergeben:
function DeineFuction(var x:Integer; var y:Integer)
begin x:=1; y:=2; end;
Delphi-Quellcode:
DeineFunction(ergebnisx,ergebnisy);
|
AW: Function mit mehreren Rückgabewerten
Zitat:
Delphi-Quellcode:
procedure DeineFuction(var x:Integer; var y:Integer);
begin x:=1; y:=2; end; |
AW: Function mit mehreren Rückgabewerten
Hmmm habs jetzt so:
Code:
Jedoch ist die zweite Messagebox immer leer
function TForm1.MoreResults(var value2 : integer);
begin Result := 1; value2 := 2; end; procedure TForm1.Button1Click(Sender: TObject); begin showmessage(MoreResults); showmessage(IntToStr(MoreResults(Value2))); end; |
AW: Function mit mehreren Rückgabewerten
Das dürfte gar nicht kompilieren.
|
AW: Function mit mehreren Rückgabewerten
Zitat:
Delphi-Quellcode:
function TForm1.MoreResults(var value2 : integer);
begin Result := 1; value2 := 2; end; procedure TForm1.Button1Click(Sender: TObject); begin showmessage(MoreResults); showmessage(IntToStr(MoreResults(Value2))); end; |
AW: Function mit mehreren Rückgabewerten
Um aber auch was konstruktives einzuwerfen hätte ich noch folgendes:
Delphi-Quellcode:
es geht sogar noch schöner :mrgreen:
type
TMoreResults = record a,b : integer; function Show : string; end; function TMoreResults.Show : string; begin Result := Format( 'Das Ergebnis ist %d und %d', [ a, b ] ); end; function MoreResults( ParameterA, ParameterB : integer ) : TMoreResults; begin Result.a := ParameterA; Result.b := ParameterB; end; procedure TForm1.Button1Click( Sender : TObject ); begin ShowMessage( MoreResults( 1, 2 ).Show ); end;
Delphi-Quellcode:
type
TMoreResults = record a,b : integer; class operator implicit( const mr : TMoreResults ) : string; end; class operator TMoreResults.implicit( const mr : TMoreResults ) : string; begin Result := Format( 'Das Ergebnis ist %d und %d', [ mr.a, mr.b ] ); end; function MoreResults( ParameterA, ParameterB : integer ) : TMoreResults; begin Result.a := ParameterA; Result.b := ParameterB; end; procedure TForm1.Button1Click( Sender : TObject ); begin ShowMessage( MoreResults( 1, 2 ) ); end; |
AW: Function mit mehreren Rückgabewerten
Hallo,
du hast wohl auch eine Form-Variable value2.
Delphi-Quellcode:
Und ja, dein Code in der IDE war anders, als du ihn hier gezeigt hast.
function TForm1.MoreResults(var theValue2 : integer): Integer;
begin Result := 1; theValue2 := 2; end; procedure TForm1.Button1Click(Sender: TObject); var iResult: Integer; iValue2: Integer; begin iResult:= MoreResults(iValue2); showmessage(IntToStr(iResult)); showmessage(IntToStr(iValue2)); end; Heiko |
AW: Function mit mehreren Rückgabewerten
Ich gehe mal davon aus das sollte:
Zitat:
Schlimmer gehts nimmer! Entweder man schreibt sich eine Prozedur und hat Seiteneffekte. Oder man schreibt sich eine Funktion. Aber die Vermischung von beidem ist einfach... siehe oben. |
AW: Function mit mehreren Rückgabewerten
Das habe ich einfach nur aus dem Kopf geschrieben und sollte auch nur zur Veranschaulichung dienen.
Aber ok. |
AW: Function mit mehreren Rückgabewerten
ich kann mich den anderen Usern nur anschließen. Nutz eine Prozedur, wenn du mehrere Rückgabewerte brauchst.
Ist einfache und weeeeeeeesentlich schöner... :wink: |
AW: Function mit mehreren Rückgabewerten
Oder eine Funktion mit Status als Rückgabewert
|
AW: Function mit mehreren Rückgabewerten
Gibt es eigentlich irgendeinen speziellen Grund, warum es hier normal zu sein scheint, reine Ausgabeparameter als "var" anstatt als "out" zu deklarieren?
Soll der Aufrufende nicht sehen können, dass er da gar nix reinpacken muss? |
AW: Function mit mehreren Rückgabewerten
Mach' ne Klasse draus, dann lösen sich die Probleme in Luft auf!
|
AW: Function mit mehreren Rückgabewerten
@SyntaxXx schreibt:
Zitat:
Schließlich bleibt es im net länger und andere lesen das gerne. Also als Funktionsergebnis kann man ein Record oder ein Array nehmen. Wie das geht, zeigt dieses Beispiel:
Delphi-Quellcode:
interface
type dreierOut: Array[1..3] of integer; function MoreResults:dreierOut; procedure berechneWas; var Ergebnis: dreierOut; Result: integer; implementation function TForm1.MoreResults:dreierOut; var a, b, c : integer; begin a := 49; b := 12; c := 66; dreierOut[1] := a; dreierOut[2] := b; dreierOut[3] := c; end; procedure TForm1.berechneWas; begin … Ergebnis:= MoreResults; // oder: Result:= MoreResults[1]; end; |
AW: Function mit mehreren Rückgabewerten
Zitat:
* als VAR-Parameter, OUT-Parameter (Letzters nur für einfache Typen, ala Integer ... NICHT für String) * als Result geht es natürlich auch * oder als Feld (Variable) in einer Klasse, wenn man Variablen und diese Funktion/Prozedur darin verpackt * oder ... |
AW: Function mit mehreren Rückgabewerten
Zitat:
Zitat:
Zitat:
Ich selber verwende aber weder var noch out, sonder benutze wie hier schon angesprochen immer Funktionen. |
AW: Function mit mehreren Rückgabewerten
Und z.B. ein String, Variant, DynArray und Interface sind gemanagte Typen, wo die Variable "initialisiert" sein muß, da Delphi den Speicher automatisch verwaltet.
Solche Typen passen da nicht zur Philosophie des OUT und OUT würde (eigentlich) das Speichermanagement schrotten. Für sowas nutze ich dann einfach Attribute oder Kommentare, als "Dokumentation".
Delphi-Quellcode:
procedure GibMir([out] Variable: string);
procedure GibMir({out} Variable: string); /// <summary> gibt mir eine Variable </summary> /// <param name="Variable"> [OUT] hier rein </param> procedure GibMir(Variable: string); |
AW: Function mit mehreren Rückgabewerten
Man könnte auch für die Rückgabe eine Klasse oder einen Record nutzen, wenn man keine VAR oder OUT in den Parametern nutzen will.
Delphi-Quellcode:
type
TBackData=class a: Integer; b: Integer; c: Integer; end; function berechneirgendwas(x, y: Integer): TBackData; begin Result:=TBackData.Create; Result.a:=x*y; Result.b:=x+y; Result.c:=x-y; end; procedure irgendwo; var backdata: TBackData; begin backdata:=berechneirgendwas(10, 5); try // mach irgendwas mit den Daten finally backdata.free; end; end; |
AW: Function mit mehreren Rückgabewerten
Wäre natürlich schön, wenn Delphi nativ Tupel unterstützen würde. Python kann das sehr schön:
Code:
In Delphi gibt es da nur drei möglichkeiten:
def give_two:
return 1, 2 one, two = give_two()
|
AW: Function mit mehreren Rückgabewerten
Zitat:
|
AW: Function mit mehreren Rückgabewerten
Zitat:
Das bedeuted der Parameter wird immer vor dem Aufruf (zumindest leer bzw. nil) initialisiert, nicht innerhalb. Eine Eigenheit die man bei Verwendung anderer Programmiersprachen berücksichtigen muss. |
AW: Function mit mehreren Rückgabewerten
Zitat:
![]() |
AW: Function mit mehreren Rückgabewerten
Noch besser ... das Result, wird bei "Managed Types" und für Typen größer der CPU-RegisterGröße (Record und Static-Array) intern als VAR-Parameter behandelt,
womit das Result nicht innerhalb der Funktion initialisiert wird, sondern beim Aufrufer, was in einer Schleife echt wunderschöne Ergebnisse liefert.
Delphi-Quellcode:
Besonders praktisch, da es für Result (wenn managed) keine Meldung gibt, dass Dieses nicht initialisiert sei (was ja prinzipiell "eigentlich" auch richtig ist, aber logisch nicht wirklich verständlich)
funtion Test: string
begin Result := Result + 'a'; end; var S: string; begin for var i := 1 to 3 do begin S := Test; ShowMessage(S); end; end; |
AW: Function mit mehreren Rückgabewerten
Zitat:
Ich finde Python hier unscharf und unklar. Die Optionen die Delphi einem gibt bedeuten mehr Schreibaufwand aber auch deutlich bessere Lesbarkeit. Gerade durch die Rückgabe oder Verwendung eines Interfaced Objektes bekommt man unendliche Freiheit. Und, das sogar ohne sich auf die Anzahl der Parameter festlegen zu müssen. Natürlich kann sowas in Speicherverschwendung ausarten. Jede Münze hat halt zwei Seiten. |
AW: Function mit mehreren Rückgabewerten
Tuple unpacking ist ein ziemlich klares und verständliches Konzept.
Was an dem Code oben etwas ungewohnt ist, ist die Typinferenz bei der give_two Funktion. Aber wenn man klareren Code schreiben will, dann kann man auch Type Hints (seit Python 3.9) und den Tuple Konstructor explizit nutzen:
Code:
def give_two() -> tuple[int,int]:
return (1, 2) |
AW: Function mit mehreren Rückgabewerten
Zitat:
Zusätzlich bin ich ein großer Freund sprechender Variablen, also könnte das auch in den meisten Fällen reichen:
Delphi-Quellcode:
Das hat sogar den schönen Vorteil, dass ich auch innerhalb der Funktion sofort weiss, was die Parameter so machen sollen.procedure GibMir( AInput, AOutput: string); begin AOutput := AInput + '...'; end; |
AW: Function mit mehreren Rückgabewerten
Zitat:
Zitat:
Delphi-Quellcode:
. Denn so macht der nen Copy-on-call und behält den zugewiesenen Wert in der Funktion. Du kannst das nur weglassen, wenn der Parameter ein Zeigertyp ist und du den Referenzwert veränderst.
out AOutput: string
|
AW: Function mit mehreren Rückgabewerten
Zitat:
|
AW: Function mit mehreren Rückgabewerten
Zitat:
|
AW: Function mit mehreren Rückgabewerten
Das ist Sache, wie Tuples implementiert werden - in C# kannst du explizite Feldnamen weglassen, oder sie definieren - siehe
![]() Ebenfalls in Python kannst du auch Named tuples nutzen, siehe ![]() Allerdings gehen viele Bestrebungen in modernen Programmiersprachen dahin, die sogenannte Cermony zu verringern, also diesen ganzen Boilerplate Code, den man so schreiben muss, damit der Compiler versteht, was man eigtl will. Gute Designs opfern hierbei wenig bis gar keine Verständlichkeit des Source Codes. |
AW: Function mit mehreren Rückgabewerten
Zitat:
|
AW: Function mit mehreren Rückgabewerten
Zitat:
Ich führ das jetzt nicht weiter aus, weil das schon sehr offtopic ist und ich keine Lust habe, ein Essay über die Thematik zu schreiben. |
AW: Function mit mehreren Rückgabewerten
Ich mache das schon seit längerem mit Records. Unter anderem auch um exceptions usw. wiederzugeben...
Delphi-Quellcode:
TSuccessRes=record
Success:Boolean; Error:String; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz