Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Array of String als Konstante klappt nicht... (https://www.delphipraxis.net/149652-array-string-als-konstante-klappt-nicht.html)

stho 26. Mär 2010 07:04


Array of String als Konstante klappt nicht...
 
Hallo liebe Delphianer

Ich habe nun (malwieder) ein Problem das ich alleine mit Googles Hilfe nicht gebacken bekomme.

Ich möchte ein Array of String in meinem Programm hinterlegen.

Wenn ich es so mache:
Delphi-Quellcode:
Const
  list : array of String = ['Test1', 'test2', 'test3'];
klappt es leider nicht...

Er sagt mir:
"Ordinaltyp erforderlich"
+
"Inkompatible Typen:'integer' und 'string'"

Wie kriege ich das gelöst? :gruebel:

Stevie 26. Mär 2010 07:11

Re: Array of String als Konstante klappt nicht...
 
Eckige Klammern sind für Sets - daher die Meldungen bzgl Ordinaltyp. Außerdem musst du die Größe deines Arrays angeben:
Delphi-Quellcode:
const
  list: array[0..2] of string = ('Test1', 'test2', 'test3');

stho 26. Mär 2010 07:14

Re: Array of String als Konstante klappt nicht...
 
okay, das ist gut zu wissen, danke :thumb:

ja, mit arrays habe ich bisher nicht viel am hut gehabt bzw. habe mich bisher gut drum gedrückt...
Aber mein Array kann in diesem Projekt sehr schnell sehr viele Werte enthalten.
Es gibt keine möglichkeit um die Aufzählung "(0..2)" weg zu lassen, oder?

jfheins 26. Mär 2010 07:16

Re: Array of String als Konstante klappt nicht...
 
Dynamische Arrays?

Die kannst du mit setlength() jederzeit anpassen ;)

Stevie 26. Mär 2010 07:17

Re: Array of String als Konstante klappt nicht...
 
Wenn dein Array noch die Größe ändern soll isses ja nicht mehr const, oder? :stupid:

stho 26. Mär 2010 07:19

Re: Array of String als Konstante klappt nicht...
 
ja nein, das meinte ich auch nicht ;-)
Mein array werde ich während der Entwicklung noch oft verändern...
Bei einer Größeren Zahl an Einträgen wird es ein bisschen unübersichtlich.

Das man arrays dynamisch vergrößern kann ist mir bekannt. jedoch soll dieses constanten-array nur von mir während der entwicklungszeit verändert werden ;-)

versteht ihr was ich meine?

himitsu 26. Mär 2010 07:32

Re: Array of String als Konstante klappt nicht...
 
Als Konstante kann man nur statische Arrays verwenden, eine automatische Zählung der nötigen Arraygröße ist leider nicht möglich, also mußt du die Größe manuell angeben.

Das Einzige was möglich ist, ware eine dynamische Array-Variable nachträglich mit dem Inhalt einer statischen Array-Konstante zu belegen.

OK, man könnte zwar auch eine dynamische Arraykonstante erstellen und schon zur CompileTime mit Werten füllen, aber der Aufwand wäre etwas wesentlich größer und es gibt dafür absolut keinen Nutzen.

stho 26. Mär 2010 08:29

Re: Array of String als Konstante klappt nicht...
 
nagut, ich bedanke mich für eure Hilfe ;-)
Bleibt mir wohl nix anderes übrig als dies Array zu zählen :-P

uligerhardt 26. Mär 2010 10:09

Re: Array of String als Konstante klappt nicht...
 
Zitat:

Zitat von stho
Bleibt mir wohl nix anderes übrig als dies Array zu zählen :-P

In neueren Delphi-Versionen zählt der Compiler für dich:
Delphi-Quellcode:
const
  list: array[0..99] of string = ('Test1', 'test2', 'test3');
ergibt
Code:
[DCC Fehler] Unit1.pas(34): E2072 Anzahl der Elemente (3) weicht von der Deklaration (100) ab

stho 26. Mär 2010 10:14

Re: Array of String als Konstante klappt nicht...
 
Zitat:

Zitat von uligerhardt
Zitat:

Zitat von stho
Bleibt mir wohl nix anderes übrig als dies Array zu zählen :-P

In neueren Delphi-Versionen zählt der Compiler für dich:
Delphi-Quellcode:
const
  list: array[0..99] of string = ('Test1', 'test2', 'test3');
ergibt
Code:
[DCC Fehler] Unit1.pas(34): E2072 Anzahl der Elemente (3) weicht von der Deklaration (100) ab

Habs grade mal ausprobiert 8-)
Das ist wirklich ne tolle sache :thumb:

Vielen dank!! :cheers:

ToFaceTeKilla 1. Apr 2010 12:15

Re: Array of String als Konstante klappt nicht...
 
Zitat:

Zitat von himitsu
Das Einzige was möglich ist, ware eine dynamische Array-Variable nachträglich mit dem Inhalt einer statischen Array-Konstante zu belegen.

Da ich das gerade brauche: gibt es da einer Möglichkeit, das in einem Rutsch zu erledigen ála:
Delphi-Quellcode:
dynarray:= staticArray;
:?:
(Dass dieser Weg nicht geht, hab ich schon gemerkt ;-)
Ansonsten muss ich das statischen eben durchlaufen.

jfheins 1. Apr 2010 13:17

Re: Array of String als Konstante klappt nicht...
 
Geht copy() nicht?

ToFaceTeKilla 1. Apr 2010 13:34

Re: Array of String als Konstante klappt nicht...
 
Ne leider nicht. Mit Copy() kann man nur von dynamischen Arrays kopieren, nicht aber auf :?

himitsu 5. Dez 2019 18:23

AW: Re: Array of String als Konstante klappt nicht...
 
Weil ich's grade sehe.

Gab es nicht irgendwo einen Array-Helper (paar mal gesehn, aber immer wenn ich es suche, dann finde ich nichts :stupid:),
der ein OpenArray (array of T) als Parameter entgegen nimmt und ein dynmaisches TArray<T> zurück gibt?
Bei OpenArrays kann man alle Array-Typen reingeben und der Compiler kopiert notfalls automatisch um.

Drinnen in dem Helper wäre dann aber auch wieder nur der StandardCode:
* SetLength und dann umkopieren der Items

Dennis07 6. Dez 2019 01:21

AW: Re: Array of String als Konstante klappt nicht...
 
Zitat:

Zitat von himitsu (Beitrag 1452843)
Gab es nicht irgendwo einen Array-Helper (paar mal gesehn, aber immer wenn ich es suche, dann finde ich nichts :stupid:),
der ein OpenArray (array of T) als Parameter entgegen nimmt und ein dynmaisches TArray<T> zurück gibt?
Bei OpenArrays kann man alle Array-Typen reingeben und der Compiler kopiert notfalls automatisch um.

Drinnen in dem Helper wäre dann aber auch wieder nur der StandardCode:
* SetLength und dann umkopieren der Items

Öff... nicht dass ich wüsste. Dürfte aber kein Hexenwerk sein...

Bezüglich
Delphi-Quellcode:
array of const
gibt es meines Wissens nach auch keine vorgefertigte Lösung, aber auch das lässt sich relativ einfach realisieren. (
Delphi-Quellcode:
function (A: array of const): TArray<TVarRec> begin Pointer(Result) := Pointer(A); end
)

Bei Strings ginge ja sowas wie
Delphi-Quellcode:
String.Join(',', MyArrayOfConst).Split(',')
, und bei anderen Typen muss man halt immer vorsichtig sein, da sie ja nicht alle Typen eines TVarRec-Objekts darstellen können. Andersherum wäre das ja, wie du sagst, eh implizit möglich.

himitsu 6. Dez 2019 10:16

AW: Re: Array of String als Konstante klappt nicht...
 
Zitat:

Zitat von Dennis07 (Beitrag 1452854)
Bezüglich
Delphi-Quellcode:
array of const
gibt es meines Wissens nach auch keine vorgefertigte Lösung, aber auch das lässt sich relativ einfach realisieren. (
Delphi-Quellcode:
function (A: array of const): TArray<TVarRec> begin Pointer(Result) := Pointer(A); end
)

NEIN, denn
Delphi-Quellcode:
array of const
ist nicht gleich
Delphi-Quellcode:
array of const
!

Als Parameter sind array of-Definitionen ein eigener Typ/Mechianismus, der intern auch komplett anders arbeitet und aufgebaut ist.
http://docwiki.embarcadero.com/RADSt...en/Open_Arrays

Dennis07 6. Dez 2019 11:28

AW: Array of String als Konstante klappt nicht...
 
Was du wohl eigentlich sagen wolltest:
Zitat:

Delphi-Quellcode:
array of const
ist nicht gleich
Delphi-Quellcode:
TArray<TVarRec>

.
Und ja, da hast du natürlich recht. Zumindest so teilweise.

Nur habe ich deshalb nicht Unrecht. Schauen wir es uns etwas genauer an:
Ein
Delphi-Quellcode:
array of const
wird vom Compiler wie ein statisches Array behandelt, obwohl es intern ein PVarRec ist. Deshalb brauchen wir einen
Delphi-Quellcode:
@
-Operator vor dem array (welchen ich gestern nicht geschrieben habe, weil ich gerade keinen Bock hatte, den Code zu testen und so nicht gemerkt habe, dass er eben nur fast richtig ist).

Somit wird folgende Funktion eben funktionieren:

Delphi-Quellcode:
function ArrayOfConstToArrayOfTVarRec(a: array of const): TArray<TVarRec>;
begin
  Pointer(Result) := Pointer(@a);
end;
etwas typsicherer wäre es dann aber doch, nicht beides nach
Delphi-Quellcode:
Pointer
zu casten, sondern das Rechte nach
Delphi-Quellcode:
TArray<TVarRec>
. Dann sieht das ganze so aus:

Delphi-Quellcode:
function ArrayOfConstToArrayOfTVarRec(a: array of const): TArray<TVarRec>;
begin
  Result := TArray<TVarRec>(@a);
end;
Kannst du ja gern testen, wenn du es mir nicht glaubst. Aber es funktioniert. ;)

Delphi-Quellcode:
Showmessage(String(ArrayOfConstToArrayOfTVarRec(['hello'])[0].VUnicodeString)); // Zeigt "hello"

himitsu 8. Dez 2019 17:43

AW: Array of String als Konstante klappt nicht...
 
ich meinte natürlich
Typ/Variable: array of xyz (das enstspricht intern TArray<xyz>)
Parameter-Definition: array of xyz

Bei deinem TVarRec mußt du aber aufpassen, dass das worauf das VarRec zeig, auch nach Aufruf der Funktion noch existiert.

Ja, dass dieses const = TVarRect, das kann ich nicht abstreiten.
Allerdings ist der Inhalt dieses Arrays nur wärend der Laufzeit der Methode gültig,
aber später können enthaltene Zeiger schnell ungültig sein. (und Strings sind Zeiger)



Delphi-Quellcode:
function ArrayOfConstToArrayOfTVarRec(A: array of const): TArray<TVarRec>;
begin
  Result := TArray<TVarRec>(@A);
end;

procedure TForm7.Button1Click(Sender: TObject);
var
  A: TArray<TVarRec>;
begin
  A := ArrayOfConstToArrayOfTVarRec(['hello' + IntToStr(0)]);
  Showmessage(String(A[0].VUnicodeString)); // zeigt "hello0"
end;
Und nun noch ein bissl Umstellen, damit der Test aus dem Scope der temporären Variable läuft, welche der Compiler für das
Delphi-Quellcode:
'hello'+...
erzeugt hatte.
Delphi-Quellcode:
function ArrayOfConstToArrayOfTVarRec(A: array of const): TArray<TVarRec>;
begin
  Result := TArray<TVarRec>(@A);
end;

procedure Test(var A: TArray<TVarRec>);
begin
  A := ArrayOfConstToArrayOfTVarRec(['hello' + IntToStr(0)]);
end;

procedure TForm7.Button1Click(Sender: TObject);
var
  A: TArray<TVarRec>;
begin
  Test(A); // peng
  Showmessage(String(A[0].VUnicodeString));
end;

TVarRec ist leider nicht so "leicht" zu benutzen, ist jedenfalls nicht vergleichbar mir Variant, TValue und allen anderen Delphi-Typen.

Dennis07 10. Dez 2019 14:46

AW: Array of String als Konstante klappt nicht...
 
Jo, so wie bei jedem anderen Array-Parameter. Dafür kann man ja den Wert kopieren via
Delphi-Quellcode:
Copy
:

Delphi-Quellcode:
function ArrayOfConstToArrayOfTVarRec(A: array of const): TArray<TVarRec>;
begin
  Result := Copy(TArray<TVarRec>(@A), Low(A), Length(A));
end;
Und Schwupps-die-Wupps funktioniert alles wieder problemlos.
Was du mit dem
Delphi-Quellcode:
+ IntToStr(0)
erreichen wolltest ist mir allerdings bisher schleierhaft. Damit funktioniert das nämlich logischerweise nicht mehr, bzw. gibt
Delphi-Quellcode:
A[0]
dann einen leeren String zurück.

himitsu 15. Dez 2019 14:04

AW: Array of String als Konstante klappt nicht...
 
Joar, ich hätte auch ein S:=Copy(S) oder UniqueString(S) benutzen können.
Wollte damit einfach erreichen, dass der String nur eine Referenz besitzt und kein Link auf eine Konstante ist, damit er eine echte Variable wird und am Ende auch wirklich abgeräumt wird.

Nja, für den perfekten Test müsste man noch FastMM dazu bringen den Speicher wirklich freizugeben.
Delphi-Quellcode:
StringOfChar('x', genügendspeicher)
war mir in dem Moment nicht eingefallen. :oops:


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