这是我想要更好理解的学术事物之一。 (我没有理由为什么会写这样的代码。)
如果您的代码以无限期类型开头,例如
type Indef is array (Integer range <>) of Integer;
My_Indef : Indef (1..2) := (3=>0, 4=>0);
这将编译并且聚合将滑动;范围将是1..2
如果你从一个明确的类型开始
type Def is array (1..2) of Integer;
My_Def : Def := (3=>0, 4=>0);
如果没有警告就不会编译,也不会在没有运行时错误的情况下运行。我不明白为什么第一个样本会滑动但第二个样本不会滑动。
答案 0 :(得分:2)
你的第二个例子是完全错误的。由于Def
是一个确定的数组类型,因此在声明该类型的对象时,不能指定/更改其约束。
如果您尝试:
type Def is array (1..2) of Integer;
My_Def : Def := (3 => 0, 4 => 0);
它会编译,但在运行时失败,不是因为它不能滑动,而是因为初始约束超出范围。
要查看确定数组类型的数组滑动工作,您可以尝试:
J_Def : Def := (2 => 2) & (2 => 1);
答案 1 :(得分:0)
感谢大家的评论。他们让我有了更深刻的理解,我想答案。相反,我创建了两个明确的类型,区别仅在于一个范围为1..2而另一个范围为3..4然后我可以将它们分配给彼此并且它们将会滑动。 但是我必须首先将右侧投射到左侧的类型,因为它们是不同的类型。我认为,这是我在问题中的两个例子之间的区别。
我在第二个例子中指定的聚合需要创建一个具有聚合范围的匿名类型的数组,然后将其转换为类型Def. Instead it creates an array of type
Def并警告我聚合已经出来
范围,我将来会遇到约束错误。
在第一个例子中,我只是创建了两个具有不同范围的Indef类型的数组,编译器正在左侧滑动聚合。
鉴于对类型安全的强调,我现在可以看到为什么编译器愿意做第一个而不是第二个。 Ada不会在其他任何地方进行自动投射,当然也不应该从这里开始。
为清楚起见,此处是示例项目的屏幕截图,其中包含代码和编译器反馈。