Domanda

Usando D2010, vorrei fare qualcosa del genere:

procedure SizeArray(var aArr: array of integer; aSize: integer);
begin
  SetLength(aArr,aSize);
end;

Ma questo non riesce a compilare. Perché il mio & Quot; aArr & Quot; Il parametro non è un array dinamico, è un parametro di array aperto. E SetLength non può essere chiamato su di esso. L'unico modo che conosco per forzare il parametro a essere un array dinamico è di dargli un nome di tipo, in questo modo:

type
  TIntArray = array of integer;

procedure SizeArray(var aArr: TIntArray; aSize: integer);
begin
  SetLength(aArr,aSize);
end;

E ora il codice viene compilato. E funziona bene, per la maggior parte, ma questo non riesce:

procedure Test;
var
  a : array of integer;
begin
  SizeArray(a,5);
end;

Poiché i tipi di parametri var effettivi e formali devono essere identici e il compilatore non riconosce " array di interi " e " TIntArray " come tipi identici.

Quindi, ecco la mia domanda: c'è un modo in cui posso fare in modo che il compilatore identifichi il mio parametro var come un array dinamico piuttosto che come un array aperto in modo che il chiamante possa dichiarare un semplice " array di interi < !> quot; piuttosto che un tipo chiamato?

Grazie in anticipo.

È stato utile?

Soluzione

Pascal, e per estensione Delphi, usa l'equivalenza dei nomi piuttosto che l'equivalenza strutturale per i tipi di array, inclusi gli array dinamici. Le variabili dichiarate con un tipo che non ha un nome, in questo modo:

var
  x: array of Integer;

... finisce per usare un nome anonimo che non è equivalente al nome di nessun altro tipo. Ecco perché ricevi l'errore. L'errore può essere utile; ad esempio, considera una matrice di Kilometers contro una matrice di Kilograms - ma spesso accade che dichiarare un nome per ogni tipo distinto sia scomodo.

Per aggirare questo problema e rimanere all'interno del sistema di tipo sicuro (evitando così parametri non tipizzati, come suggerisce skamradt), consiglio di usare lo stesso nome per ogni particolare forma di array. Puoi farlo in misura ragionevolmente ampia usando il tipo TArray<T> dichiarato nell'unità di sistema. Quindi, invece di lavorare con array of Integer, usa TArray<Integer>.

<=> è dichiarato in questo modo:

type
  TArray<T> = array of T;

... in modo che possa fornire un nome per array dinamici arbitrari.

Altri suggerimenti

Questo è davvero possibile ... basta usare la parola chiave assoluta insieme a una variante non tipizzata

procedure SizeArray(var aArr; aSize: integer);
var
  ActArr : Array of Integer absolute aArr;
begin
  SetLength(ActArr,aSize);
end;

var
  Test : Array of Integer;
begin
  SizeArray(Test,5);
  showMessage(IntTostr(High(Test)));  // -- returns 4
end;

No, non c'è modo di farlo. Fa parte delle specifiche del linguaggio Pascal e non è probabile che cambi.

EDIT: Skamradt ha trovato un modo. Vorrei ribadirlo. Non c'è modo di farlo in modo sicuro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top