Frage

Ich war auf der Suche auf Delphi: Array von Char und TCharArray "Inkompatible Typen" und begann zu experimentieren. Was ich entdeckte, ist ziemlich interessant.

procedure Clear(AArray: array of Integer);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := 0;
end;

var
  MyArray: array of Integer;
begin
  Clear(MyArray);
end.

Dieses einfache kleines Beispiel zeigt, wie Sie eine dynamische Array an eine Prozedur übergeben können, ein offenen Array-Parameter verwenden. Es kompiliert und läuft genau wie erwartet.

procedure Clear(AArray: array of Char);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

var
  MyArray: array of Char;
begin
  Clear(MyArray);
end.

Hier ist nahezu identisch Code der einzige Unterschied ist es eine Reihe von Char verwendet statt Integer. Es ist nicht zu kompilieren. Stattdessen wird der Compiler spuckt:

 E2010 Incompatible types: 'Array' and 'Dynamic array'

Warum sollte das sein?

Nach einer Suche, während ich entdeckte dieser QC Bericht. Ich bin mit Delphi 2009 und seine immer noch geschieht.

War es hilfreich?

Lösung

Da speziell die Dokumentation erwähnt offene Array-Parameter vom Typ Char mit dynamischen Arrays kompatibel zu sein, soll dies ein Fehler sein. Aus 'Open Array Parameter' :

function Find(A: array of Char): Ganze Zahl; Cover: [...]
Hinweis: [...] Der voriges Beispiel wird eine Funktion dass nimmt jede Anordnung von Elementen Char, einschließlich (aber nicht beschränkt auf) dynamische Arrays. [...]

Andere Tipps

Sie können mit dieser Art von Array arbeiten, Ihre eigene Art definieren:

type
  TCharDynArray = array of char;

procedure Clear(AArray: TCharDynArray);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

procedure test;
var
  MyArray: TCharDynArray;
begin
  Clear(MyArray);
end;

Dieser Code wird kompiliert in Ordnung. Es tut nichts nützlich natürlich (der aArray Parameter wird nicht als „var“ gesetzt, so dass es auf dem Stack kopiert wird, bevor ein # 0 zu jedem Elemente zuweisen). Aber zumindest, es kompiliert wird.

In der Praxis fand ich leichter heraus zu definieren oder die Verwendung auf hohe Ebene von Typen für dynamische Arrays (wie TIntegerDynArray), weil es zumindest ermöglicht es Ihnen, das Array als Referenz zu übergeben, ein var daher vermieden werden ein machen kopieren Sie auf dem Stapel, und machen Sie Ihren Code schneller.

Über die Zuordnung zu einem PChar, ist es üblich, für alle dynamischen Arrays: Sie TIntegerDynArray auf einen Zeiger zuordnen können, dann verwenden, als PInteger oder PIntegerArray:

procedure AddInteger(var Values: TIntegerDynArray; Value: integer);
var n: integer;
begin
  n := Length(Values);
  SetLength(Values,n+1);
  Values[n] := Value;
end;

procedure Loop(V: PInteger);
begin
  if V<>nil then
    while V^<>0 do begin
      write(V^,' ');
      inc(V); // go to next integer in array
    end;
end;

var IntArray: TIntegerDynArray;
begin
  Loop(pointer(IntArray)); // will display nothing, since pointer(IntArray)=nil for IntArray=[]
  AddInteger(IntArray,2);
  AddInteger(IntArray,3);
  AddInteger(IntArray,0);
  Loop(pointer(IntArray)); // will display '2 3 '  
end.

Das Problem ist der "array of char" Code inkonsistent beeing mit "array of integer" ist sicher in Compiler intrinsics, und die Tatsache, dass ein PChar typ gegossen in eine Zeichenfolge sein kann.

Ich denke, der Grund ist, dass array of Char kompatibel ist mit PChar, wie dieser Code nicht kompiliert:

procedure Clear(AArray: array of Char);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

var
  MyArray: array of Char;
  P: PChar;
begin
  Clear(P^);
end.

Das ist wahrscheinlich aus historischen Gründen.
Hoffentlich Barry Kelly oder Danny Thorpe wird in kicken und etwas mehr Feedback zu diesem Thema geben.

- jeroen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top