Возможно ли это: массив в записи

#arrays #delphi #record

#массивы #delphi #запись

Вопрос:

У меня есть следующие массивы

 NAMES1: array[0..1] of string = ('NO1','NAME1');
NAMES2: array[0..1] of string = ('NO2','NAME2');
  

и структура записи

 TMyRec = record(
  Name: ????;
);
  

В результате мне нужно объявить постоянный массив записей следующим образом

 const
  StringArraysList: array[0..1] of TMyRec = (
    (Name: NAMES1),
    (Name: NAMES2)
  );
  

Вопрос в том, какой тип я должен выбрать для имени в TMyRec?

Ответ №1:

Вам нужно сделать это так:

 type
  TTwoNames = array[0..1] of string;

  TMyRec = record
    Names: TTwoNames;
  end;

const
  StringArraysList: array[0..1] of TMyRec = (
    (Names: ('NO1','NAME1')),
    (Names: ('NO2','NAME2'))
  );
  

Вы бы предпочли написать окончательное объявление как

 const
  NAMES1: TTwoNames = ('NO1','NAME1');
  NAMES2: TTwoNames = ('NO2','NAME2');

  StringArraysList: array[0..1] of TMyRec = (
    (Names: NAMES1),
    (Names: NAMES2)
  );
  

Но это приводит к

[Ошибка DCC] Unit1.pas(38): ожидается постоянное выражение E2026

Некоторые константы Delphi не такие постоянные, как хотелось бы!

В документации для констант записи указано, что

Значения должны быть представлены постоянными выражениями.

В документации для типизированных констант указано, что

Типизированные константы не могут встречаться в постоянных выражениях.

Соедините эти два правила вместе, и мы получим E2026 .

Комментарии:

1. Спасибо за ответ. Как насчет случая, когда мне понадобится новый массив, размер которого отличается. Например, следующее: NAMES3: массив [0..2] string = (‘NO3′,’NAME3’, ‘ЧТО-ТО ЕЩЕ’); Таким образом, я не могу объявить TTwoNames как массив из двух элементов.

2. Тогда вы вообще не сможете сделать это как константу. Тогда вам нужен динамический массив, который вы назначаете во время выполнения.

3. Я всегда склонен рассматривать «истинные константы» как «именованные литералы», т. Е. Они являются просто символическими заменами литералов.

4. @Yura: Если вы хотите использовать динамические массивы, вы можете во время выполнения использовать SetLength, а затем устанавливать каждый элемент по одному, но вы также можете сделать: MyArray := TStringDynArray.Create('NO3', 'NAME3', 'SMTH ELSE'); используя синтаксис конструктора для dynarrays .

Ответ №2:

Вы могли бы объявить новый тип

 TName = array[0..1] of string;
  

и используйте это в объявлении вашей записи.
Затем ваше объявление становится

 type
  TName = array[0..1] of string;

  TMyRec = record
    Name: TName;
  end;

const
  StringArraysList: array[0..1] of TMyRec = (
    (Name: ('NO1','NAME1')),
    (Name: ('NO2','NAME2'))
  );