Массив вариантных записей в Аде - PullRequest
2 голосов
/ 04 ноября 2010

Я хочу объявить массив с типом элемента записи варианта. Примерно так:

type myStruct (theType : vehicleType) is
record
...
when car => numOfWheels : Positive;
when others => null;
end record;

myArray : array (Positive range <>) of myStruct;

Но в этом случае я получаю ошибку. Это позволяет только:

myArray : array (1.100) of myStruct(Car); //such as

Так, как решить проблему индекса и как описать массив типа записи типа, не давая его дискриминанта?

Ответы [ 2 ]

3 голосов
/ 05 ноября 2010

Пример выше не скомпилируется.Вот правильная версия (я изменил mystruct на Integer для простоты):

procedure test_array is
subtype Vehicle_Array_Index is Integer range 1..100; --// Maximum size is 100
type Arr_T is array (Vehicle_Array_Index range <>) of Integer;
type Vehicle_Array (Size: Vehicle_Array_Index := 1) is record
   Vehicles : Arr_T(1..Size);
end record;
begin
  null;
end;

Одна из ошибок заключалась в том, что вы не можете иметь анонимные массивы внутри записей, и, во-вторых, вы должны использовать дискриминант для ограничения массиваinside.

Как уже упоминалось выше, это не очень хорошее решение для массивов различной длины, так как, скорее всего, вы все равно получите массив максимального размера.Если вам нужны массивы с динамически определяемыми размерами, вы можете использовать для этого блоки.

declare
  a: array(1..n) of integer; -- n can be a variable here
begin
--some code using a
end;

Это также работает в частях объявления процедур и функций, где n может быть параметром, передаваемым подпрограмме (одно из преимуществАда имеет более C / C ++).И, конечно, вы можете просто динамически размещать массивы в куче с помощью распределителей.

2 голосов
/ 04 ноября 2010

Если вы хотите иметь возможность создавать объекты различимого типа и изменять (или выяснять), что это за тип во время выполнения, , вы должны задать дискриминанту значение по умолчанию в объявлении.

Причина этого заключается в том, что Ада не хочет беспокоиться о том, чтобы иметь дело с неинициализированными различимыми объектами, которые она даже не может выяснить, размер и допустимые поля записи.

По этой причине, а также по некоторым причинам, о которых я немного расскажу в комментариях, записи, отличающиеся от Ada, на самом деле не очень полезны в программировании на разных языках (например: точно дублирование объединения C). Они могут быть удобны на своих условиях.

Для приведенного вами примера вы должны сделать следующее (предупреждение: не скомпилировано):

type myStruct (theType : vehicleType := car) is 
record 
... 
when car => numOfWheels : Positive; 
when others => null; 
end record; 

Тогда вы можете установить одно из значений массива во время выполнения следующим образом:

myArray(20) := (theType => car, 
                field1  => myArray(20).field1, 
                ... , --// Fill in the rest of the fields by name 
                numberOfWheels => 4);

Что касается этой части: myArray: массив (Положительный диапазон <>) myStruct;

Вы не можете объявить фактические объекты массива с неопределенным диапазоном, как это. Вы можете объявить тип таким образом, но объект должен иметь фактический размер. Если вам нужен массив переменной длины, вы можете еще раз использовать вариант записи. (Опять не скомпилировано)

subtype Vehicle_Array_Index is Integer range 1..100; --// Maximum size is 100
type Vehicle_Array (Vehicle_Array_Index : Size := 1) is record
   Vehicles : array (Vehicle_Array_Index range <>) of myStruct;
end record;

О, и еще одна вещь. Вы не делаете этого в своем примере, но если вы когда-нибудь захотите использовать свой дискриминант для размера массива, как указано выше, будьте осторожны. Когда вы объявляете объекты этого типа (опять же, при условии, что вы использовали значение по умолчанию для дискриминанта), компилятор попытается зарезервировать достаточно места для максимально возможного размера, для которого вы могли бы указать значение. Это делает Очень плохой идеей , чтобы создать дискриминируемый массив, индексированный чем-то с огромным диапазоном, например Integer или Positive Я знаю, что в наши дни компьютеры больше, но все же у большинства людей нет 4 гигабайтов на один маленький глупый массив. Поэтому, если вы используете свой дискриминант в качестве индекса массива, было бы неплохо создать меньший подтип Integer для использования в качестве типа дискриминанта.

...