Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Default-Wert für Record in Methode (https://www.delphipraxis.net/203439-default-wert-fuer-record-methode.html)

backdraft 17. Feb 2020 12:02

Default-Wert für Record in Methode
 
Hallo,

ist es nicht möglich einen Record vorinitialisiert in eine Methode zu übergeben?

Code:
type
  TMyRecord = record
    MyVar: string;
  end;

const
  cMyRecord : TMyRecord = (MyVar: 'Hello world');

type
  TMyClass = class
  public
    procedure HelloWorld(const aMyVar: TMyRecord = cMyRecord);
  end;
Meldet in der "procedure" Zeile:
[dcc32 Fehler] Unit1.pas(21): E2268 Parameter dieses Typs dürfen keine Standardwerte haben
[dcc32 Fehler] Unit1.pas(21): E2026 Konstantenausdruck erwartet

Ist meine Syntax falsch?

Danke
Oliver

Stevie 17. Feb 2020 12:09

AW: Default-Wert für Record in Methode
 
cMyConst ist eine typisierte Konstante und nicht benutzbar für default parameter Werte.

himitsu 17. Feb 2020 12:11

AW: Default-Wert für Record in Methode
 
Zitat:

Zitat von Stevie (Beitrag 1457687)
cMyConst ist eine typisierte Konstante und nicht benutzbar für default parameter Werte.

Leider, obwohl es ja eigentlich keinen Grund gibt, warum das nicht gehen sollte.


Es ginge hier nur der Parameter als Pointer und dann innen ein
Delphi-Quellcode:
if not Assigned(aMyVar) then aMyVar := cMyRecord;
oder das beliebte
Delphi-Quellcode:
procedure HelloWorld(const aMyVar: TMyRecord); overload;
procedure HelloWorld(); overload;

sakura 17. Feb 2020 12:14

AW: Default-Wert für Record in Methode
 
Als Alternative eine Methode ohne den Record-Parameter definieren, mit overload markieren und darin den Record initialisieren und die eigentliche Methode aufrufen.

...:cat:...

backdraft 17. Feb 2020 14:59

AW: Default-Wert für Record in Methode
 
Beide Ideen hatte ich auch, mit dem Pointer und dem overload.
Aber ich dachte einfach, ich bin zu doof, weil ein Record doch zu Pascal gehört, seitdem es existiert.
Ich werde es dann per overload machen.

himitsu 17. Feb 2020 15:51

AW: Default-Wert für Record in Methode
 
Nee, geht leider nicht ... k.A. warum.

Delphi fügte ja auch nur die Werte direkt dort in den Aufrufen ein, wo die Parameter fehlen, drum wäre es nicht schwer sich die Referenz auf diese Konstante zu merken und sie an den Stellen zu verwenden.


Tipp: Für Property wurde das Default erweitert, denn "eigentlich" kann man nur ordinale Werte bis 32 Bit dort verwenden (Integer),
aber da gibt es nun was von Ratio.. mit Parametern.
Delphi-Quellcode:
property i: Integer read ... write ... default 123;

[Default('abc')]
property S: string read ... write ...;
http://docwiki.embarcadero.com/Libra...faultAttribute

Dennis07 17. Feb 2020 20:43

AW: Default-Wert für Record in Methode
 
Der Grund ist relativ simpel: Anders, als bei einfachen Typen oder offenen Strings/Arrays, entspricht der übergebene Wert im Record-Parameter nicht dem tatsächlichen übergebenen Wert in der Funktion. Record-Parameter werden tatsächlich als Zeiger übergeben, allerdings kannst du bei Record-Typen keine manuelle Dereferenzierung als Parameter vornehmen.
Sprich, obwohl es ein Zeiger ist, hast du keinen Zugriff auf diesen als Zeiger und schonmal überhaupt keinen auf diesen als Wert.
Das ist auch der Grund, weshalb die Signatur einer Funktion, die ein PMyRecord entgegennimmt zwar identisch mit einer ist, die ein TMyRecord entgegennimmt, allerdings du in der einen den echten Zeiger aufrufen kannst und in der anderen nur den dereferenzierten.
Da du in Delphi keine Zeiger auf Konstanten deklarieren kannst, ist es demnach also nicht möglich, einer Funktion einen Default-Wert vom Typen eines Records zu übergeben.

EDIT: Und bevor hier noch einer gleich mit "das geht aber doch bei Strings" anfängt: String-Konstanten sind KEINE "echten" Konstanten, sondern nur Zeiger-Konstanten.

himitsu 18. Feb 2020 10:29

AW: Default-Wert für Record in Methode
 
Pssst: Record ... kein Array (ja, ich weiß dass für Delphi Records auch nur Arrays mit nur einer Ebene sind, zumindestens bei den Funktionen zur Initialisierung des Speichers)

Jupp, aber wenn du den Record zerlegst, dann sind darin nur typen, die Delphi normal (einzeln und ohne Typ) auch übergeben kann.
Und hier ist der Record sogar genau mit einer typisierten String-Konstante identisch.

Delphi-Quellcode:
var
  Form1: TForm1;

type
  TMyRecord = {record
    MyVar:} string;
  {end;}

const
  cMyRecord : TMyRecord = {(MyVar:} 'Hello world'{)};

type
  TMyClass = class
  public
    procedure HelloWorld(const aMyVar: TMyRecord = cMyRecord);
  end;

original: [DCC Fehler] E2268 Parameter dieses Typs dürfen keine Standardwerte haben
jetzt:   [DCC Fehler] E2026 Konstantenausdruck erwartet
E2268 ergibt eigentlich keinen Sinn
und so lange die Typen übereinstimmen, ergibt E2026 auch keinen Sinn,
warum der Compiler sowas nach 25 Jahren immernoch nicht kann, gerade beim String
Pointer ist Pointer, und vor allem da sich hier Variable, Konstante und typisierte Konstante garnicht unterscheiden.

Dennis07 18. Feb 2020 11:27

AW: Default-Wert für Record in Methode
 
Naja, logisch betrachtet magst du ja Recht haben, aber ein Record, wenngleich er auch nur einen einzigen Wert beinhaltet, wird vom Compiler nunmal als Record betrachtet und unterliegt somit den Typenbeschränkungen eines solchen.
Ein Record, der nur einen String beinhaltet, ist immer noch ein Record und kein String. Das macht aber auch irgendwie Sinn, denn es ist somit in jedem Fall zu 100% klar, wie sich dieser verhält. Stell dir mal vor, du hast folgenden Record:

Delphi-Quellcode:
TMyRec = record
  Value: String;
  class operator Implicit(AValue: String): TMyRec;
end;
Und jetzt weißt du diesem Record einen String-Wert zu. Was soll denn jetzt passieren? Soll er den Operator, oder den impliziten Zuweisungsbefehl verwenden? Aber okay, sagen wir jetzt mal, dass es eindeutig sei und er sich für eins von beiden entscheiden würde. Dann fällt uns ein, dass wir am Record noch einen Zweiten Wert benötigen, und ändern diesen entsprechend ab. Und jetzt kompiliert das gesamte Programm plötzlich nicht mehr, bzw. es macht Blödsinn (je nach dem, was vorher passiert ist)? Ich denke nicht, dass das eine sehr sinnvolle Spracherweiterung wäre. Die extrem wenigen Fälle, wo das wirklich sinnvoll wäre, müssten dann mit enormem Programmieraufwand bei allen anderen eingebüßt werden.
Noch nicht einmal fände ich es Sinnvoll, wenn Arrays der Länge 1 mit entsprechenden Variablen kompatibel wären, und das käme sicher noch mit weniger Problem einher.

Zitat:

Zitat von himitsu (Beitrag 1457758)
Pssst: Record ... kein Array (ja, ich weiß dass für Delphi Records auch nur Arrays mit nur einer Ebene sind, zumindestens bei den Funktionen zur Initialisierung des Speichers)

Najaaaaa, wenn du von statischen Arrays redest, dann vielleicht. Nur können ja statische Arrays aus genau dem selben Grund keine Standardwerte haben. Und dynamische Arrays bekommen nur ein offenes Array als Standardwert, das am Anfang der Methode zu einem dynamischen Array konvertiert wird.

Stevie 18. Feb 2020 12:27

AW: Default-Wert für Record in Methode
 
Im Grund genommen ist die Lösung mit der Überladung sowieso die sauberere, denn eine Änderung daran ist kein API Breaking Change.

Höh, wie jetzt? Ja, schonmal eine Routine mit einem Default Parameter aus Modul X in Modul Y aufgerufen, dann den Default Wert geändert und nur Modul X neu kompiliert und gewundert?


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:30 Uhr.
Seite 1 von 2  1 2      

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