Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Function mit mehreren Rückgabewerten (https://www.delphipraxis.net/157726-function-mit-mehreren-rueckgabewerten.html)

SyntaxXx 22. Jan 2011 13:06

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:
function MoreResults:string;
begin
a := 1;
b := 2;
end;
Wie kann ich nun in einer anderen Function auf a und b zugreifen?

Wie gesagt, mit Result bekomme ich ja nur einen Wert zurück.

Ich hoffe ihr könnt mir helfen

Klaus01 22. Jan 2011 13:13

AW: Function mit mehreren Rückgabewerten
 
Hallo,

Du könntest als Result ein Record verwenden.

Grüße
Klaus

WM_CLOSE 22. Jan 2011 13:17

AW: Function mit mehreren Rückgabewerten
 
entweder du deklarierst einen Record
Delphi-Quellcode:
type
  TDeinRecord=record
    x:Integer;
    y:Integer;
  end;
oder du übergibst der function Var-Parameter
Delphi-Quellcode:
function DeineFuction(var x:Integer; var y:Integer)
begin
  x:=1;
  y:=2;
end;
Dabei musst du die variablen aus der aufrufenden funktion übergeben:
Delphi-Quellcode:
DeineFunction(ergebnisx,ergebnisy);

Sir Rufo 22. Jan 2011 13:27

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von WM_CLOSE (Beitrag 1076541)
oder du übergibst der function Var-Parameter
Delphi-Quellcode:
function DeineFuction(var x:Integer; var y:Integer)
begin
  x:=1;
  y:=2;
end;
Dabei musst du die variablen aus der aufrufenden funktion übergeben:
Delphi-Quellcode:
DeineFunction(ergebnisx,ergebnisy);

Eine Function muss immer einen Rückgabewert haben, also wird das so nicht gehen

Delphi-Quellcode:
procedure DeineFuction(var x:Integer; var y:Integer);
begin
  x:=1;
  y:=2;
end;

SyntaxXx 22. Jan 2011 13:31

AW: Function mit mehreren Rückgabewerten
 
Hmmm habs jetzt so:

Code:
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;
Jedoch ist die zweite Messagebox immer leer

Luckie 22. Jan 2011 13:32

AW: Function mit mehreren Rückgabewerten
 
Das dürfte gar nicht kompilieren.

Sir Rufo 22. Jan 2011 13:36

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von SyntaxXx (Beitrag 1076545)
Hmmm habs jetzt so:

Code:
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;
Jedoch ist die zweite Messagebox immer leer

Und nach über 100 Beiträgen sollte man auch die Delphi-Tags kennen
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;

Sir Rufo 22. Jan 2011 13:46

AW: Function mit mehreren Rückgabewerten
 
Um aber auch was konstruktives einzuwerfen hätte ich noch folgendes:

Delphi-Quellcode:
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;
es geht sogar noch schöner :mrgreen:
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;

hoika 22. Jan 2011 13:57

AW: Function mit mehreren Rückgabewerten
 
Hallo,

du hast wohl auch eine Form-Variable value2.

Delphi-Quellcode:
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;
Und ja, dein Code in der IDE war anders, als du ihn hier gezeigt hast.


Heiko

Meflin 22. Jan 2011 14:05

AW: Function mit mehreren Rückgabewerten
 
Ich gehe mal davon aus das sollte:

Zitat:

Zitat von SyntaxXx (Beitrag 1076545)
Code:
function TForm1.MoreResults(var value2 : integer): integer;
begin
Result := 1;
value2 := 2;
end;

heißen, aber... :kotz:

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.

SyntaxXx 22. Jan 2011 14:14

AW: Function mit mehreren Rückgabewerten
 
Das habe ich einfach nur aus dem Kopf geschrieben und sollte auch nur zur Veranschaulichung dienen.

Aber ok.

hans ditter 22. Jan 2011 16:35

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:

mkinzler 22. Jan 2011 21:05

AW: Function mit mehreren Rückgabewerten
 
Oder eine Funktion mit Status als Rückgabewert

Elvis 22. Jan 2011 21:54

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?

sx2008 23. Jan 2011 14:12

AW: Function mit mehreren Rückgabewerten
 
Mach' ne Klasse draus, dann lösen sich die Probleme in Luft auf!

nettoplus 10. Dez 2024 11:04

AW: Function mit mehreren Rückgabewerten
 
@SyntaxXx schreibt:
Zitat:

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)

markierenCode:
function MoreResults:string;
begin
a := 1;
b := 2;
end;
Diese Anfrage ist schon ziemlich alt, seit dem hat sich bei Delphi viel neu entwickelt. Deswegen beschloss ich die Antworten etwas zu ergänzen.
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;

himitsu 10. Dez 2024 14:19

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von nettoplus (Beitrag 1544075)
Delphi-Quellcode:
interface

var
Ergebnis: dreierOut;
Result: integer;

procedure TForm1.berechneWas;

Globale Variable: NEIN, schäm dich :!: :warn:


* 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 ...

freimatz 10. Dez 2024 14:40

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von himitsu (Beitrag 1544085)
* oder ...

Im Result ein Datentransfer-Objekt

Zitat:

Zitat von Elvis (Beitrag 1076597)
Gibt es eigentlich irgendeinen speziellen Grund, warum es hier normal zu sein scheint, reine Ausgabeparameter als "var" anstatt als "out" zu deklarieren?

das out wurde erst später in Delphi implementiert. Also ich vermute eines dieser drei: Gewohnheit, Faulheit und/oder Ignoranz.

Zitat:

Zitat von Elvis (Beitrag 1076597)
Soll der Aufrufende nicht sehen können, dass er da gar nix reinpacken muss?

Ich meine Ja.
Ich selber verwende aber weder var noch out, sonder benutze wie hier schon angesprochen immer Funktionen.

himitsu 10. Dez 2024 14:49

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

Hobbycoder 10. Dez 2024 14:59

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;

Dennis07 11. Dez 2024 13:43

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:
def give_two:
  return 1, 2

one, two = give_two()
In Delphi gibt es da nur drei möglichkeiten:
  1. Du gibst ein Array oder IEnumerable-Objekt zurück
  2. Du deklarierst die einen Record und gibst ihn zurück
  3. Du verwendest out- (oder var-) Parameter

freimatz 11. Dez 2024 14:55

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von Dennis07 (Beitrag 1544100)
... nur drei ...

Nein.

Blup 12. Dez 2024 14:40

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von freimatz (Beitrag 1544086)
Zitat:

Zitat von Elvis (Beitrag 1076597)
Gibt es eigentlich irgendeinen speziellen Grund, warum es hier normal zu sein scheint, reine Ausgabeparameter als "var" anstatt als "out" zu deklarieren?

das out wurde erst später in Delphi implementiert. Also ich vermute eines dieser drei: Gewohnheit, Faulheit und/oder Ignoranz.

Man muss nur wissen das Delphi für gemanagte Typen out tatsächlich als var implementiert.
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.

Stevie 12. Dez 2024 14:50

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von Blup (Beitrag 1544139)
Das bedeuted der Parameter wird immer vor dem Aufruf (zumindest leer bzw. nil) initialisiert, nicht innerhalb.

Eigentlich sogar beides - siehe https://delphisorcery.blogspot.com/2...t-bad-var.html

himitsu 12. Dez 2024 15:22

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

Sinspin 12. Dez 2024 16:27

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von Dennis07 (Beitrag 1544100)
Wäre natürlich schön, wenn Delphi nativ Tupel unterstützen würde. Python kann das sehr schön:
Code:
def give_two:
  return 1, 2

one, two = give_two()
In Delphi gibt es da nur drei möglichkeiten:
  1. Du gibst ein Array oder IEnumerable-Objekt zurück
  2. Du deklarierst die einen Record und gibst ihn zurück
  3. Du verwendest out- (oder var-) Parameter

Wärend die Schlange nur zischt, hat das Orakel Antworten.

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.

Stevie 13. Dez 2024 02:24

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)

Rollo62 13. Dez 2024 07:03

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von himitsu (Beitrag 1544087)
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);

Ja, sehr schön.

Zusätzlich bin ich ein großer Freund sprechender Variablen, also könnte das auch in den meisten Fällen reichen:
Delphi-Quellcode:

procedure GibMir( AInput, AOutput: string);
begin
    AOutput := AInput + '...';
end;
Das hat sogar den schönen Vorteil, dass ich auch innerhalb der Funktion sofort weiss, was die Parameter so machen sollen.

Dennis07 15. Jan 2025 18:11

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von freimatz (Beitrag 1544103)
Nein.

Bitte nicht so ausführliche Kommentare schreiben, mein Gehirn kann die nicht verarbeiten.

Zitat:

Zitat von Rollo62 (Beitrag 1544158)
Delphi-Quellcode:
procedure GibMir( AInput, AOutput: string);
begin
    AOutput := AInput + '...';
end;

Du meinstest wohl
Delphi-Quellcode:
out AOutput: string
. 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.

Rollo62 16. Jan 2025 06:11

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von Dennis07 (Beitrag 1545255)
Du meinstest wohl
Delphi-Quellcode:
out AOutput: string
.

Ja klar ...

jaenicke 16. Jan 2025 06:59

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von Stevie (Beitrag 1544155)
Tuple unpacking ist ein ziemlich klares und verständliches Konzept.

Verständlich ist es schon, aber wie in Delphi bei Methoden mit vielen Parametern unübersichtlich. Da finde ich benannte Argumente in C# deutlich besser. Entsprechend finde ich es auch besser, wenn man einen Record oder ähnliches zurückbekommt, so dass man mit Namen auf die Werte zugreift und nicht z.B. über Tupel basierend auf der Reihenfolge.

Stevie 16. Jan 2025 11:21

AW: Function mit mehreren Rückgabewerten
 
Das ist Sache, wie Tuples implementiert werden - in C# kannst du explizite Feldnamen weglassen, oder sie definieren - siehe https://learn.microsoft.com/en-us/do...s/value-tuples
Ebenfalls in Python kannst du auch Named tuples nutzen, siehe https://www.slingacademy.com/article...uple-examples/ - das kommt eigtl schon fast an eine Deklaration eines expliziten Recordtyps heran, was wir auch in Delphi machen können.

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.

jaenicke 16. Jan 2025 13:34

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von Stevie (Beitrag 1545272)
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.

In dem Fall geht es ja um die Lesbarkeit und Wartbarkeit für den Entwickler, nicht um etwas, das der Compiler braucht. Ich bin kein Freund davon, möglichst wenige Buchstaben zu schreiben, sondern finde gute und schnelle Lesbarkeit viel wichtiger.

Stevie 17. Jan 2025 10:18

AW: Function mit mehreren Rückgabewerten
 
Zitat:

Zitat von jaenicke (Beitrag 1545280)
Zitat:

Zitat von Stevie (Beitrag 1545272)
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.

In dem Fall geht es ja um die Lesbarkeit und Wartbarkeit für den Entwickler, nicht um etwas, das der Compiler braucht. Ich bin kein Freund davon, möglichst wenige Buchstaben zu schreiben, sondern finde gute und schnelle Lesbarkeit viel wichtiger.

Korrekt, es geht um die Essenz und nicht um den ganzen Extraklump (aka Ceremony) - gute Languagedesigner (von denen es gar nicht so viele gibt) achten darauf, dass gerade nicht die Lesbarkeit und Verständlichkeit des Codes leidet sondern verbessert wird, da man keine kognitive Leistung damit verplempert, im Kopf den ganzen Extraklump durchzuparsen. Natürlich sind bei langjährigem Gebrauch bestimmte Synapsen schon ausgetreten und so mancher meint, dass dies und das weniger lesbar oder verständlich ist. Das ist aber genauso als ob ich behaupte, dass chinesisch total schwierig und unverständlich ist, nur weil ich es nicht kann. Milliarden von Menschen würden mir da vermutlich widersprechen.

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.

QuickAndDirty 17. Jan 2025 15:27

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