È un array dinamico di Char consentito quando il tipo di parametro è aperto serie di Char?
-
04-10-2019 - |
Domanda
I stava guardando Delfi: matrice di Char e TCharArray "Tipi incompatibili" e iniziato a sperimentare. Quello che ho scoperto è piuttosto interessante.
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.
Questo semplice piccolo esempio mostra come è possibile passare un array dinamico a una procedura utilizzando un parametro aperto di allineamento. Esso viene compilato ed eseguito esattamente come previsto.
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.
Ecco codice quasi identico con la sola differenza che utilizza una matrice di Char
anziché Integer
. Esso non può essere compilato. Invece il compilatore sputa fuori:
E2010 Incompatible types: 'Array' and 'Dynamic array'
Perché questo sarebbe?
Dopo aver cercato per un po 'ho scoperto questo rapporto QC . Io corro Delphi 2009 e la sua ancora accadendo.
Soluzione
Poiché la documentazione menziona specificamente parametri array aperti di tipo char per essere compatibile con gli array dinamici, questo dovrebbe essere un problema. Da 'Open Array Parametri' :
function Find(A: array of Char):
Numero intero;
[...]
Nota: [...] Il Nell'esempio precedente crea una funzione che prende qualsiasi array di elementi Char, compresi (ma non limitati a) dinamica array. [...]
Altri suggerimenti
Si può lavorare con questo tipo di matrice, che definisce il proprio tipo:
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;
Questo codice verrà compilato bene. Non fa nulla di utile, naturalmente (il parametro AArray non è impostato come "var", quindi è copiato sullo stack prima di assegnare un # 0 per ogni articolo). Ma almeno, si compila.
In pratica, ho scoperto più facile definire o uso di alto livello di tipi di matrici dinamiche (come TIntegerDynArray), perché almeno consente di passare la matrice come riferimento, utilizzando una var, evitando così di effettuare una copiare sulla pila, e rendere il vostro codice più veloce.
A proposito della mappatura a un PChar, è usuale per tutti gli array dinamici: è possibile associare un TIntegerDynArray a un puntatore, quindi utilizzarlo come un PInteger o un 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.
Il problema è il codice "vettore di char" beeing incompatibile con "matrice di integer" è certamente in intrinseci compilatore, e il fatto che una PChar può essere di tipo pressofuso in una stringa.
Credo che il motivo è che array of Char
è compatibile con PChar
, come fa questo codice di compilazione:
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.
Questo è probabilmente per ragioni storiche.
Speriamo Barry Kelly o Danny Thorpe entreranno in gioco e fornire un po 'di feedback su questo.
- Jeroen