Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi function mit zwei Rückgabewerten? (https://www.delphipraxis.net/75739-function-mit-zwei-rueckgabewerten.html)

Hansi 24. Aug 2006 10:43


function mit zwei Rückgabewerten?
 
Hey,

Ich habe einen function geschrieben die mir einen Rückgabewert liefert und zwar ein String. Nun möchte ich aber dass die Function mir, wenn ich einen StringA reinliefere, einen StringB und einen IntegerA zurückgibt.

Wie mache ich sowas?

Gausi 24. Aug 2006 10:44

Re: function mit zwei Rückgabewerten?
 
Nimm eine Prozedur mit zwei VAR-PArametern.

TBx 24. Aug 2006 10:47

Re: function mit zwei Rückgabewerten?
 
Delphi-Quellcode:
function MachWas (StringA : String; var IntegerA : integer) : string;
Parameter, die mit var angegeben werden, werden nach Funktionsaufruf an den Aufrufer zurückgegeben.

Hope it helps

onlinekater

shmia 24. Aug 2006 10:51

Re: function mit zwei Rückgabewerten?
 
Alternativ nimmst du einen Record. Dies macht vorallem dann Sinn, wenn es mal mehr wie 2 Rückgabewerte sind oder wenn du schon mehrere Inputparameter hast.
Delphi-Quellcode:
TErgebnis = record
   Name : string;
   Anzahl : integer;
end;
procedure MachWas(var erg:TErgebnis);

Hansi 24. Aug 2006 10:53

Re: function mit zwei Rückgabewerten?
 
Danke euch dreien...

Ich probiere den Ansatz mit dem record mal.

mfg
Hansi

ManuMF 24. Aug 2006 10:57

Re: function mit zwei Rückgabewerten?
 
Ich hätte auch ein Record vorgeschlagen, aber als Rückgabewert:
Delphi-Quellcode:
// Typendefinition
type
  TStringAndInt = Record
    rString: String;
    rInteger: Integer;
  end;

// Irgendwo im Code ;-)

function Test: TStringAndInt;
begin
  result.rString := 'Test';
  result.rInteger := 123;
end;

// Und zum Ausführen

procedure TForm1.Button1Click(Sender: TObject);
var
  Rueckgabe: TStringAndInt;
begin
  Rueckgabe := Test;
  Showmessage(Rueckgabe.rString + ' ' + IntToStr(Rueckgabe.rInteger));
end;
Du musst dazu wie oben im code in der Prozedur / Funktion, die etwas mit dem Rückgabewert machen soll, diesen noch mal als Variable definieren, sonst musst du deine Funktion mehrfach aufrufen:
Delphi-Quellcode:
Showmessage(Test.rString + ' ' + IntToStr(Test.rInteger));
Aber das geht natürlich auf Kosten der Geschwindigkeit.

Helmi 24. Aug 2006 11:01

Re: function mit zwei Rückgabewerten?
 
Hallo

oder du verwendest "out"

Delphi-Quellcode:
procedure Test(out i: Integer; out S: String);
begin
  i := 123;
  S := DP;
end;
[edit]Delphi-Tags vergessen! Sorry! [/edit]

Neutral General 24. Aug 2006 11:34

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von Helmi
Hallo

oder du verwendest "out"

Delphi-Quellcode:
procedure Test(out i: Integer; out S: String);
begin
  i := 123;
  S := DP;
end;
[edit]Delphi-Tags vergessen! Sorry! [/edit]

OT: Aber das muss sein: "Undefinierter Bezeichner 'DP'." :mrgreen:

Also es gibt wie gesagt nur die 2-3 drei Möglichkeiten die ich grad nochmal zusammenfasse damit ich nicht nur OT geschrieben hab :mrgreen:

1. Function gibt ein Record zurück

Delphi-Quellcode:
ABC = record
 A: String
 B: Integer;
 C: Boolean;
end;

function GetaABC: ABC;
begin
 ABC.A := 'Hallo';
 ABC.B := 22;
 ABC.C := true;
end;
2. Proceduren mit Out-Parametern
Delphi-Quellcode:
procedure GiveMeAnA(out AA: String);
begin
 AA:= 'A';
end;
3. Das gleiche mit Var-Parametern.

Gruß
Neutral General

Hansi 24. Aug 2006 11:36

Re: function mit zwei Rückgabewerten?
 
Hallo ManuMF,

Leider habe ich dich an dem einen Punkt mit dem zweifachen aufrufen nicht ganz verstanden.
Bis jetzt habe ich:

Das deklariert:
Delphi-Quellcode:
type
    Ttest = Record
    test_String: String;
    test_Integer: Integer;
  end;
dann die function:
Delphi-Quellcode:
Function test(StringA: String): Ttest;
und rufe über:
Delphi-Quellcode:
s := test(Edit1.Text).test_String;
i := test(Edit1.Text).test_Integer;
die function auf.
Nur wird diese 2x durchlaufen.

Wie kann ich das verhindern?

3_of_8 24. Aug 2006 11:38

Re: function mit zwei Rückgabewerten?
 
Delphi-Quellcode:
with test(Edit1.Text) do
begin
  s := test_String;
  i := test_Integer;
end;

H4ndy 24. Aug 2006 11:43

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von Hansi
Nur wird diese 2x durchlaufen.
Wie kann ich das verhindern?

Zitat:

Zitat von 3_of_8
Delphi-Quellcode:
with test(Edit1.Text) do
begin
  s := test_String;
  i := test_Integer;
end;

Also with ... do finde ich nicht soo toll, da kann man fix mal durcheinander kommen :?
Besser wäre (vorallem wenn noch mehr mit dem Ergebnis gearbeitet wird):
Delphi-Quellcode:
var Ergebnis: TTest;
...
Ergebnis := test(Edit1.Text);
s := Ergebnis.test_String;
i := Ergebnis.test_Integer;

DGL-luke 24. Aug 2006 11:49

Re: function mit zwei Rückgabewerten?
 
Ihr castet einen string auf einen record? find ich jetzt sehr gewagt... :shock:

EDIT: uppsala... sorry, verlesen :oops:

---Bernhard--- 24. Aug 2006 11:52

Re: function mit zwei Rückgabewerten?
 
Hi!

Muss kurz was richtig stellen
Zitat:

Zitat von Neutral General
1. Function gibt ein Record zurück

Delphi-Quellcode:
ABC = record
 A: String
 B: Integer;
 C: Boolean;
end;

function GetaABC: ABC;
begin
 ABC.A := 'Hallo';
 ABC.B := 22;
 ABC.C := true;
end;

Du musst 'result' verwenden:
Delphi-Quellcode:
ABC = record
  A: String
  B: Integer;
  C: Boolean;
end;

function GetABC: ABC;
begin
  result.A := 'Hallo';
  result.B := 22;
  result.C := true;
end;
Und dann hätte ich noch nen kleinen Vorschlag um das Zwischenspeichern des Records zu vermeiden, nämlich die Verwendung von "with .. do .." :

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  with GetABC do
  begin
    showmessage(A);
    showmessage(IntToStr(B));
    showmessage(BoolToStr(C, true));
  end;
end;
edit: ups, der with do Vorschlag hatte ja schon jemand gepostet :oops:

RavenIV 24. Aug 2006 11:56

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von 3_of_8
Delphi-Quellcode:
with test(Edit1.Text) do
begin
  s := test_String;
  i := test_Integer;
end;

Das mit dem with macht die ganze Sache noch unübersichtlicher.
Und die Funktion wird trotzdem 2x durchlaufen, weil 2x darauf zugrgriffen wird.

Die beste Lösung bisher ist das mit dem Ergebnis := ...

jfheins 24. Aug 2006 12:04

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von RavenIV
Zitat:

Zitat von 3_of_8
Delphi-Quellcode:
with test(Edit1.Text) do
begin
  s := test_String;
  i := test_Integer;
end;

Und die Funktion wird trotzdem 2x durchlaufen, weil 2x darauf zugrgriffen wird.

Ich wette dagegen, ich glaube, Delphi legt eine Variable an, mit dem Inhalt und greift immer darauf zu ... :mrgreen:

JasonDX 24. Aug 2006 12:06

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von RavenIV
Das mit dem with macht die ganze Sache noch unübersichtlicher.
Und die Funktion wird trotzdem 2x durchlaufen, weil 2x darauf zugrgriffen wird.

Nee, ganz sicher nicht. with ist mehr eine Hilfe beim programmieren, der Compiler schert sich (grob gesehn) so gut wie gar nicht drum, ob da jetzt ein with steht oder ned. Fuer ihn ist es beides mal das selbe. Naemlich wird das Ergebnis auf den Stack gepusht, und er greift dann ueber [esp+offset] auf die einzelnen Elemente zu.

greetz
Mike

ManuMF 24. Aug 2006 12:06

Re: function mit zwei Rückgabewerten?
 
@RavenIV: genau.
Hier noch mal dazu mein Code von oben:

Zitat:

Zitat von ManuMF
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Rueckgabe: TStringAndInt;
begin
  Rueckgabe := Test;
  Showmessage(Rueckgabe.rString + ' ' + IntToStr(Rueckgabe.rInteger));
end;


3_of_8 24. Aug 2006 12:19

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von RavenIV
Zitat:

Zitat von 3_of_8
Delphi-Quellcode:
with test(Edit1.Text) do
begin
  s := test_String;
  i := test_Integer;
end;

Das mit dem with macht die ganze Sache noch unübersichtlicher.
Und die Funktion wird trotzdem 2x durchlaufen, weil 2x darauf zugrgriffen wird.

Die beste Lösung bisher ist das mit dem Ergebnis := ...

Unsinn.

Delphi-Quellcode:
with test('wuppdi') do
begin
showmessage(inttostr(i));
showmessage(s);
end;
wird zu:
Delphi-Quellcode:
lea edx,[ebp-$08]
mov eax,$004521b8
call test
lea edx,[ebp-$0c]
mov eax,[ebp-$04]
call IntToStr
mov eax,[ebp-$0c]
call ShowMessage
mov eax,[ebp-$08]
call ShowMessage
No further comment.

oldmax 24. Aug 2006 12:26

Re: function mit zwei Rückgabewerten?
 
Hi
Ich hatte keine Lust, jede Antwort auszuwerten, aber im Prinzip hab ich's schon durchgeschaut. Der Nachteil der Parameterübergabe mit Vatist, das du sehr schnell eine Variable veränderst, die du gar nicht geändert haben möchtest. Daher hier mal eine andere Lösung.

Delphi-Quellcode:
Function MyForm.Machwas(String_A : String): String;
Var String_B : String;
     Zahl    : Integer;
begin
  .... machwas mit String_A ......
  .... setze String_B und den Wert der Zahl
  Result:=String_B+';'+IntToStr(Zahl);
end;
Aufruf im Programm
Delphi-Quellcode:
.....
ZweiWerteStr:=Machwas(einString);
StringAntwort:=Copy(ZweiWerteStr,1, Pos(';',ZweiWerteStr)-1);
ZahlAntwort:=StrToInt(Copy(ZweiWerteStr, Pos(';',ZweiWerteStr)+1,Length(ZweiWerteStr)-Pos(';',ZweiWerteStr)));

....
Zugegeben, etwas kompliziert, daher ersetze ich meist bei solchen sachen das Ergebnis Pos(...) unter Zuhilfenahme von xPos

Delphi-Quellcode:
....
xPos:=Pos(';',ZweiWerteStr);
StringAntwort:=Copy(ZweiWerteStr,1, xPos-1);
ZahlAntwort:=StrToInt(Copy(ZweiWerteStr, xPos+1,Length(ZweiWerteStr)-xPos));
....
Wenn du gut im Stringzerlegen bist, kannst du soviele Werte zurückliefern wie du willst. Übrigends, das Semikolon nehme ich meist, weil es in Wörtern halt nicht vorkommt, genausogut kannst du Unterstrich oder irgendwas anderes nehmen, um die Werte zu trennen.
Gruß oldmax

JasonDX 24. Aug 2006 12:47

Re: function mit zwei Rückgabewerten?
 
:shock: Alles in einen String umwandeln und zusammenfassen, und einen String zurueckgeben? :shock:
Mal abgesehn davon, dass ein einbeiniger Esel im Rueckwaertslaufen schneller sein wird als diese Implementierung, hast du noch ein Problem, wenn ich im Record einen String habe, der ein ; enthaelt. Dann musst du noch zusaetzlich alles Escapen. Weiters schwierig wirds dann, wenn ich im Record einen weiteren Record habe, oder andere Typen, die man nicht ohne groesseren Aufwand in Strings umwandeln kann.
Sry, aber die string-Methode ist *etwas* [....] Mir faellt das richtige Wort dafuer nicht ein, aber strunzdoof kommt gut hin

Zitat:

Zitat von oldmax
Der Nachteil der Parameterübergabe mit Vatist, das du sehr schnell eine Variable veränderst, die du gar nicht geändert haben möchtest.

Na ja, bei der Ergebnisvariable waer schon ganz gut, wenn die Prozedur/Funktion diese veraendern wurde :gruebel:

greetz
Mike

3_of_8 24. Aug 2006 12:50

Re: function mit zwei Rückgabewerten?
 
Wie bitte? Du willst tatsächlich alles in einen String speichern? Du weißt schon, dass das unglaublich ineffezient ist? Erstmal muss Speicher für den String reserviert werden, dann wird der alte String in den neuen kopiert, dann wird der Wert (Integer, Float, wasweißich) nach String gecastet und in den String reingespeichert und beim auslesen das ganze nochmal umgekehrt und zusätzlich Schleifengefummel mit pos.

Das ist eine absolut unsaubere und langsame Methode. Benutze records oder vars, wobei ich eher zu records tendiere.

Wenn du eine Variable nicht ändern willst, dann deklariere den Parameter einfach ohne var. Oder, falls du var brauchst, deklariere dir eine Hilfsvariable, in die du den Wert speicherst.

Edit: @JasonDX: Das Wort ist "noobig".

Garfield 24. Aug 2006 14:07

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von ---Bernhard---
Du musst 'result' verwenden:

Man sollte Result verwenden. Es ist auch möglich den Namen der Funktion zu verwenden.

Neutral General 24. Aug 2006 14:57

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von Garfield
Zitat:

Zitat von ---Bernhard---
Du musst 'result' verwenden:

Man sollte Result verwenden. Es ist auch möglich den Namen der Funktion zu verwenden.

...was zu Pascal-Zeiten die einzige Möglichkeit war ;)
Hatte das weiter oben aus Zeitmangel bisschen falsch gehabt... :oops:

RavenIV 24. Aug 2006 15:17

Re: function mit zwei Rückgabewerten?
 
/ganz schön offtopic inzwischen

Zitat:

Zitat von JasonDX
Nee, ganz sicher nicht. with ist mehr eine Hilfe beim programmieren,

Meiner Meinung nach ist with eine Hilfe für schreibfaule Programmierer.
es ist kontraproduktiv, wenn ich erst schauen muss, zu welchem with die Variable jetzt gehört. Und ganz toll wird es bei verschachtelten with.

Und hast Du mal mit D7 debuggen müssen, wenn im Code einige with drin sind?
Der Debugger kann das dann nämlich nicht auflösen und zeigt beim drüberfahren keinen Wert für die Variable an.

Delphi-Quellcode:
with taMeineTabelle do
begin
  ...hier sind 20 Zeilen Code...
  Database := MeineDatenbank;
  TableName := MeineTabelle;
  Open;
  FieldByName ('MeinFeld').AsString := MeinString;
  ...hier ist nochmehr Code...
end;
ist das vielleicht übersichtlich?

JasonDX 24. Aug 2006 15:28

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von RavenIV
Zitat:

Zitat von JasonDX
Nee, ganz sicher nicht. with ist mehr eine Hilfe beim programmieren,

Meiner Meinung nach ist with eine Hilfe für schreibfaule Programmierer.
es ist kontraproduktiv, wenn ich erst schauen muss, zu welchem with die Variable jetzt gehört. Und ganz toll wird es bei verschachtelten with.

Klar, ich kann jedes Konstrukt so verwenden, dass ich den Code anschliessend nicht mehr lesen kann, aber fuer mich ist bspw. ein
Delphi-Quellcode:
with MyContactlist.GetPerson('') do
begin
  FirstName := '';
  SurName := '';
  Address := '';
  Age := 0;
  //...
end;
weitaus uebersichtlicher als das:
Delphi-Quellcode:
MyContactlist.GetPerson('').FirstName := '';
MyContactlist.GetPerson('').SurName := '';
MyContactlist.GetPerson('').Address := '';
MyContactlist.GetPerson('').Age := 0;//...
Wie immer geht es also darum, wann, wo und wie ich das ganze verwende, und bei welcher Anwendung die Vorteile ueberwiegen.

Um das nicht als Pure-OT-Post dastehn zu lassen:

IMO sind Delphi-Referenz durchsuchenvar/Delphi-Referenz durchsuchenout die beste Moeglichkeit, solangs nicht zu viele Parameter werden. Bei 2 gehts eigentlich noch ziemlich gut, aber wenn mehrere Rueckgabeparameter gebraucht werden, sollte ein Record verwendet werden. (Ob dies dann ueber CallByReference oder Rueckgabewert erledigt wird, bleibt dem Programmierer ueberlassen ;) )

greetz
Mike

PS: Gibts auch Programmierer, die nicht schreibfaul sind? :duck: ;)

himitsu 24. Aug 2006 15:39

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von JasonDX
weitaus uebersichtlicher als das:
Delphi-Quellcode:
MyContactlist.GetPerson('').FirstName := '';
MyContactlist.GetPerson('').SurName := '';
MyContactlist.GetPerson('').Address := '';
MyContactlist.GetPerson('').Age := 0;//...

nicht nur das ... ohne WITH wird auch MyContactlist.GetPerson('') mehrmals aufgerufen .... in deinem Beispiel nur einmal mit WITH und 4-mal ohne :warn:

Elvis 24. Aug 2006 16:11

Re: function mit zwei Rückgabewerten?
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von JasonDX
weitaus uebersichtlicher als das:
Delphi-Quellcode:
MyContactlist.GetPerson('').FirstName := '';
MyContactlist.GetPerson('').SurName := '';
MyContactlist.GetPerson('').Address := '';
MyContactlist.GetPerson('').Age := 0;//...

nicht nur das ... ohne WITH wird auch MyContactlist.GetPerson('') mehrmals aufgerufen .... in deinem Beispiel nur einmal mit WITH und 4-mal ohne :warn:

Deshalb mag ich das hier:
Delphi-Quellcode:
with person := MyContactlist.GetPerson('') do
begin
  person.FirstName := 'blabla'
  person.BlaBla...
end;
Da Nick Hodges jetzt der Delphi PM ist könnte sowas oder etwas ähnliches bald Einzug in Delphi finden.[1]
Er hasst with wahrscheinlich sogar noch mehr als ich und bereits ich bekomme davon allergischen Ausschlag... ;)

[1]Wobei sie es ähnlich wie die Delphi.Net Generics, die ich bis jetzt gesehen habe absichtlich nicht wie in Chrome aussehen lassen werden. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 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