我想声明一个包含变量记录的元素类型的数组。 像这样:
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
那么如何解决索引问题以及如何描述变量记录类型的数组而不给它判别?
答案 0 :(得分:3)
上面的例子不会编译。这是一个正确的版本(为简单起见,我将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;
其中一个错误是您不能在记录中包含匿名数组,其次,您应该使用判别式来约束内部数组。
如上所述,对于变长数组而言,这不是一个好的解决方案,因为最有可能你会得到一个最大尺寸的数组。如果您希望数组具有动态确定的大小,则可以使用块。
declare
a: array(1..n) of integer; -- n can be a variable here
begin
--some code using a
end;
它也适用于过程和函数的声明部分,其中n可以是传递给子程序的参数(Ada优于C / C ++的优点之一)。当然,您可以使用分配器在堆上动态分配数组。
答案 1 :(得分:2)
如果您希望能够创建有区别类型的对象并更改(或弄清楚)运行时类型是什么,您必须在声明中为判别式提供默认值。
原因是Ada不想担心处理未初始化的歧视对象,甚至无法弄清楚其大小和有效记录字段。
由于这个原因,以及我在评论中稍微讨论的一些原因,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的数组(正范围&lt;&gt;);
您无法声明具有此类不确定范围的实际数组对象。您可以通过这种方式声明类型,但对象必须具有实际大小。如果需要不同长度的数组,可以再次使用变体记录。 (再次,未编译)
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子类型以用于判别式的类型。