Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Unterschied zwischen Variant und Generics (https://www.delphipraxis.net/180668-unterschied-zwischen-variant-und-generics.html)

Gravitar 6. Jun 2014 09:07

Delphi-Version: 5

Unterschied zwischen Variant und Generics
 
Hallo,

bin gerade dabei mir Swift anzuschauen. Dort bin ich über die Beschreibung zu Generics gestolpert und habe mich gefragt, wo eigentlich der Unterschied zwischen dem Datentyp Variant in Delphi und dem Datentyp Generic in Swift ist.

Hier mal das exemplarische Beispiel einer Vertauschfunktion (SwapToValues) von zwei Werten (egal welchen Typs) in Swift:

Code:
    func swapTwoValues<T>(inout a: T, inout b: T) {
      let temporaryA = a
      a = b
      b = temporaryA
    }
In Delphi (7) würde das Ganze mit Variant nun so aussehen:

Delphi-Quellcode:
Procedure swapTwoValues(Var a,b:Variant)
var
  temporaryA : variant;
begin
  temporaryA := a;
  a := b;
  b := temporaryA;
end;
Auch diese Procedure läßt sich mit beliebigen Typen (int, float, string...) aufrufen und taucht die Werte gegeneinander aus.

Wo ist jetzt also der große Unterschied?

Neutral General 6. Jun 2014 09:12

AW: Unterschied zwischen Variant und Generics
 
Hallo,

Generics funktionieren z.B. auch mit Records :mrgreen:
Ansonsten liegt die Stärke auch eher in generischen Klassen (und dazugehörigen) generischen Methoden.

Hast du dir schon mal die generischen Listen in Delphi angeschaut? Sowas kriegst du nicht mit Varianten hin.

himitsu 6. Jun 2014 09:38

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von Gravitar (Beitrag 1261549)
Auch diese Procedure läßt sich mit beliebigen Typen (int, float, string...) aufrufen und taucht die Werte gegeneinander aus.

Hast du das ausprobiert?

Das sollte so aber nicht gehn, denn VAR-Parameter und übergebene Variable müssen eigentlich den selben Typ besitzen. :gruebel:
Und genau da haben die Generics ihren Vorteil, denn man kann den Typ ändern auswählen.

Gravitar 6. Jun 2014 09:49

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von himitsu (Beitrag 1261563)
Hast du das ausprobiert?


Jup, mit INT und STRING habe ich das getestet. Klar ist natürlich, dass a und b den gleichen Typ haben müssen. Dies galt aber auch bei dem Swift-Beispiel.

himitsu 6. Jun 2014 10:40

AW: Unterschied zwischen Variant und Generics
 
Ich meinte das so:
Delphi-Quellcode:
var
  a, b: Variant;
  x, y: Integer;
begin
  SwapTwoValues(a, b);
  SwapTwoValues(x, y); // geht nicht
end;
Natürlich ist es nahezu egal, was man in die Variant-Variablen rein packt, (der Funktion ist es total egal, nur es passt nicht alles in einen Variant rein)

aber man kann meine keine Variablen anderer Typen übergeben und genau das meinte ich.

Sir Rufo 6. Jun 2014 10:56

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von Gravitar (Beitrag 1261566)
Zitat:

Zitat von himitsu (Beitrag 1261563)
Hast du das ausprobiert?


Jup, mit INT und STRING habe ich das getestet. Klar ist natürlich, dass a und b den gleichen Typ haben müssen. Dies galt aber auch bei dem Swift-Beispiel.

Bei dem Swift-Beispiel kann diese Prüfung schon beim Kompilieren erfolgen. Bei den Variants fällt das erst zur Laufzeit auf.

himitsu 6. Jun 2014 11:19

AW: Unterschied zwischen Variant und Generics
 
Ja, das ist bei den Generics auch ein Vorteil ... die Typsicherheit.

Wobei der Beispielfunktion das nicht auffällt, da der ja egal ist, was im Variant steckt.
Aber grundsätzlich stimmt das.

Für ein paar Projekte hatte ich mir da z.B. einen Record selber geschrieben, da Default-ArrayProperty nicht überladen werden konnten.
Das war dann ein kleiner Record, welcher über implizite Casts mit String oder Integer gefüllt werden konnte, so daß das die Parameter des Property nur die beiden Typen annehmen konnten, wohingegen der Variant ja erstmal alles rein lässt (was er versteht).

Gravitar 6. Jun 2014 13:57

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von himitsu (Beitrag 1261583)
Ich meinte das so:
Delphi-Quellcode:
var
  a, b: Variant;
  x, y: Integer;
begin
  SwapTwoValues(a, b);
  SwapTwoValues(x, y); // geht nicht
end;
Natürlich ist es nahezu egal, was man in die Variant-Variablen rein packt, (der Funktion ist es total egal, nur es passt nicht alles in einen Variant rein)

aber man kann meine keine Variablen anderer Typen übergeben und genau das meinte ich.

Ja, stimmt. In Swift ist mit Generics das hier möglich:

Code:
    var someInt = 3
    var anotherInt = 107
    swapTwoValues(&someInt, &anotherInt)
    // someInt is now 107, and anotherInt is now 3
   
    var someString = "hello"
    var anotherString = "world"
    swapTwoValues(&someString, &anotherString)
    // someString is now "world", and anotherString is now "hello"
In Delphi darf ich nur Variants übergeben und erhalte natürlich auch nur Variants zurück. Dort könnte ich z.B. auch a= "Hallo" und b = 5 übergeben. Dies würde dann in der Procedure krachen. Swift läßt sowas nicht zu. Schon der Aufruf schlägt wegen unterschiedlicher Typen fehl.

himitsu 6. Jun 2014 14:03

AW: Unterschied zwischen Variant und Generics
 
In Delphi ist das mit den Generics auch möglich. :wink:
(seit 5 Jahren und seit 7 in der .Net-Ecke)

Neutral General 6. Jun 2014 14:22

AW: Unterschied zwischen Variant und Generics
 
In Delphi:

Delphi-Quellcode:
procedure TForm1.swapTwoValues<T>(var Value1, Value2: T);
var tmp: T;
begin
  tmp := Value1;
  Value1 := Value2;
  Value2 := tmp;
end;
Aufruf:

Delphi-Quellcode:
swapTwoValues<Integer>(someInt1, someInt2);
swapTwoValues<String>(someStr1, someStr2);
swapTwoValues<TMyRecord>(someRec1, someRec2);

Dejan Vu 6. Jun 2014 20:33

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von Neutral General (Beitrag 1261626)
Delphi-Quellcode:
swapTwoValues<Integer>(someInt1, someInt2);
swapTwoValues<String>(someStr1, someStr2);
swapTwoValues<TMyRecord>(someRec1, someRec2);

Und in Delphi muss man die Typen wirklich explizit angeben? In C# kann man verzichten, da der Compiler den Typen auflösen kann. Da geht also:
Delphi-Quellcode:
swapTwoValues(someInt1, someInt2);
swapTwoValues(someStr1, someStr2);
swapTwoValues(someStruct1, someStruct2);

Neutral General 7. Jun 2014 00:03

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von Dejan Vu (Beitrag 1261649)
Und in Delphi muss man die Typen wirklich explizit angeben?

Jo aber das hat mich bisher eigentlich noch nicht so gestört und ich glaube ich finde das auch übersichtlicher.. (Vllt. auch weil ichs nicht anders gewohnt bin)

Dejan Vu 7. Jun 2014 06:32

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von Neutral General (Beitrag 1261658)
Jo aber das hat mich bisher eigentlich noch nicht so gestört und ich glaube ich finde das auch übersichtlicher...

Mich stört alles überflüssige. Und hier interessieren mich die Typen nicht (=Geschmackssache).

Zum Thema: Generics dürften schneller sein, als Variants. Der Overhead ist zwar nicht besonders (obwohl man immer sagt, Variants seien soooo langsam), aber in intensiven Iterationen oder Schleifenoperationen macht sich das dann bemerkbar. Auch der Speicherverbrauch ist bei Variants etwas höher. Der Overhead ist weitgehend konstant, sodaß sich dies sehr stark bei kleinen Datentypen bemerkbar macht.

Stevie 7. Jun 2014 08:26

AW: Unterschied zwischen Variant und Generics
 
Zitat:

Zitat von Dejan Vu (Beitrag 1261649)
Und in Delphi muss man die Typen wirklich explizit angeben? In C# kann man verzichten, da der Compiler den Typen auflösen kann.

Das nennt sich Typinferenz und funktioniert in Delphi nicht mit var oder out Parametern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:55 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz