Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize a constant that is a dynamic array of fixed arrays?

Tags:

delphi

Can I initialize a constant dynamic array of arrays?

If:

type
  tNamePair = array[1..2] of String;
  tPairList = array of tNamePair;

How can I create an initialized constant? I can't get the code below compile:

const
  PairList: tPairList = ( ('One', '1'), 
                          ('Two', '2'),
                          ('Three', '3'));

If that's not possible, can a constant fixed array be initialized with a fixed array:

 type
    tPairList: array[1..3] of tNamePair;

If that's not possible, can a constant dynamic array be initialized with a record:

tNamePair = record 
              English: String;
              Number: String;
            end;           
tPairList = array of tNamePair;

if that's not possible can a constant fixed array be initialized with a record:

tNamePair = record 
              English: String;
              Number: String;
            end;           
tPairList = array[1..3] of tNamePair;

If that's not possible, any suggestions other than just hardwiring assignments in the code, which frankly would have taken me less time than composing this question!

like image 328
RobertFrank Avatar asked May 09 '12 23:05

RobertFrank


People also ask

What is a fixed heap dynamic array?

A fixed heap-dynamic array is one in which the subscript ranges are dynamically bound, and the storage allocation is dynamic, but they are both fixed after storage is allocated.


2 Answers

Prior to XE7 you could not create dynamic array constants. Constants have to be known at compile time, but dynamic arrays are allocated at runtime.

A fixed array of fixed arrays can be declared at compile-time:

type
  tNamePair = array[1..2] of String;
  tPairList = array[1..3] of tNamePair;

const
  PairList: tPairList = ( ('One', '1'),
                          ('Two', '2'),
                          ('Three', '3'));

A fixed array of records can also be declared at compile-time:

type
  tNamePair = record
              English: String;
              Number: String;
            end;
  tPairList = array[1..3] of tNamePair;

const
  PairList: tPairList = ( (English: 'One'; Number: '1'),
                          (English: 'Two'; Number: '2'),
                          (English: 'Three'; Number: '3'));

If you need a dynamic array, you have to construct it at run-time. You can either build it up directly:

type
  tNamePair = array[1..2] of String;
  tPairList = array of tNamePair;

var
  PairList: tPairList;

initialization
  SetLength(PairList, 3);
  PairList[0][1] := 'One';
  PairList[0][2] := '1';
  PairList[1][1] := 'Two';
  PairList[1][2] := '2';
  PairList[2][1] := 'Three';
  PairList[2][2] := '3';
end.

Or you can define a compile-time constant fixed array and copy it into the dynamic array at run-time:

type
  tNamePair = array[1..2] of String;
  tPairList = array[1..3] of tNamePair;
  tPairListDyn = array of tNamePair;

const
  PairList: tPairList = ( ('One', '1'),
                          ('Two', '2'),
                          ('Three', '3'));

function MakePairListDyn(const Pairs: tPairList): tPairListDyn;
var
  I, J: Integer;
begin
  SetLength(Result, Length(Pairs));
  J := 0;
  for I := Low(Pairs) to High(Pairs) do begin
    Result[J] := Pairs[I];
    Inc(J);
  end;
end;

var
  Pairs: tPairListDyn;

initialization
  Pairs := MakePairListDyn(PairList);
end.

For the situation post XE7 see @LURD's answer.

like image 126
Remy Lebeau Avatar answered Sep 24 '22 08:09

Remy Lebeau


In XE7 it is possible to declare dynamic array constants.

Simple case:

const
  a: TArray<String> = ['Delphi','XE7'];

In your example this compiles:

type
  tNamePair = TArray<String>;
  tPairList = TArray<tNamePair>;

const
  PairList: tPairList = [['One', '1'],['Two', '2'],['Three', '3']];

To create a dynamic array of a record, it can be done at runtime like this:

Type
  TNamePair = record
    English: String;
    Number: String;
    class function Define(_English,_Number: String): TNamePair; static;
  end;
  TPairList = TArray<TNamePair>;

class function TNamePair.Define(_English, _Number: String): TNamePair;
begin
  Result.English := _English;
  Result.Number := _Number;
end;

var
  pl : TPairList;
begin
  pl := [TNamePair.Define('A','1'),TNamePair.Define('B','2')];
  ...
end;
like image 26
LU RD Avatar answered Sep 22 '22 08:09

LU RD