【问题标题】:Passing arrays to different ADA package将数组传递给不同的 ADA 包
【发布时间】:2014-04-03 22:24:46
【问题描述】:

我在 Ada 中有一个任务,它要求我将多个数组传递给与我的主代码不同的包内的一个过程。我四处寻找,但“解决方案”似乎并没有解决我的情况,让我更加困惑。

我已经看到了必须将数组定义为类型 (TYPE IntArray IS ARRAY (Integer RANGE <>) OF Integer) 的示例,但这似乎只在同一个包中从一个过程传递到另一个过程时才有效 - 我如何共享数组 包之间?

    --multistack.ads
        GENERIC
...
           TYPE Item IS PRIVATE;
           WITH PROCEDURE Put(Job: IN Item);
           PACKAGE MultiStack IS
...
              TYPE IntArray IS ARRAY (Integer RANGE <>) OF Integer;      
              TYPE StackArray IS ARRAY (Integer RANGE <>) OF Item;

              Base:IntArray(1..NumberOfStacks);
...
           END MultiStack;

--stackmove.ads
    WITH MultiStack;
        GENERIC
          TYPE Item IS PRIVATE;
          PACKAGE StackMove IS
             PROCEDURE ReallocateArray(Base:IN OUT MultiStack.IntArray);
     END StackMove;

我最终得到错误stackmove.ads:13:160: invalid prefix in selected component "MultiStack"

【问题讨论】:

  • 为什么不起作用?如果您遇到错误,请发布一些代码,让我们知道您遇到了什么错误。
  • 我不知道你在上什么样的大学课程,但是如果你的课程需要你将来在 Ada 工作,我强烈建议你阅读 Barnes 的书。
  • 您在问题最后一段中显示的错误消息是指第 13 行第 160 列,但您显示的代码只有 7 行,而且少于 160 列。

标签: arrays package ada


【解决方案1】:

如果您在包Package_1的规范(可见部分)中定义了一个类型Int_Array,并且您想在包Package_2中引用该类型,则需要使用with子句来制作该类型名称可见:

with Package_1;
package Package_2 is

    procedure Something (A : Package_1.Int_Array);

    -- .........

end Package_2;

with Package_1;  use Package_1;
package Package_2 is

    procedure Something (A : Int_Array);

    -- .........

end Package_2;

需要with Package_1 才能使Package_1 中定义的任何内容可用。即使这样,您也必须在此处定义的任何标识符前面使用限定符Package_1.,以让编译器知道在哪里可以找到它。 use Package_1 表示您可以使用在 Package_1 中定义的名称而无需该限定符。但是,使用use 会使读者更难分辨名称的来源,尤其是当您use 的软件包过多时。对于是否使用use以及何时使用,不同的Ada程序员有不同的看法。

如果这不是问题,请发布更多信息。

更多:好的,既然你的包是generic,你有一个完全不同的问题。

通用包MultiStack 实际上并没有定义您可以使用的类型IntArray。您可以使用它的唯一方法是实例化泛型。如果您将Inst 定义为泛型的一个实例,如下所示:

package Inst is new MultiStack (Item => Some_Type, Put => Some_Put_Procedure);

那你可以参考Inst.IntArray。但是MultiStack.IntArrayMultiStack 本身之外永远不会是合法的。

因此,要使其与 StackMove 一起使用,有两种可能性,您需要根据自己的需求来决定:(1) 将有一个您已经拥有的特定实例 My_Multistack实例化,StackMove 可以使用; (2) 更有可能的是,您希望StackMoveMultiStack 的任何实例一起工作。如果(1)是正确的,那么只需将stackmove.ads 中的MultiStack 更改为My_MultiStack。但是如果你想要 (2),你需要一个通用的正式包

with MultiStack;
generic
    type Item is private;
    with package Stack_Instance is new MultiStack(<>);
package StackMove is
    procedure ReallocateArray (Base : in out Stack_Instance.IntArray);
end StackMove;

(你可以把ItemStack_Instance按任意顺序排列。)

执行上述操作并不能保证Stack_Instance 被实例化为与StackMove 相同的Item。如果你想保证:

with MultiStack;
generic
    type Item is private;
    with package Stack_Instance is new MultiStack(Item => Item, Put => <>);
package StackMove is
    procedure ReallocateArray (Base : in out Stack_Instance.IntArray);
end StackMove;

那么StackMove 将仅适用于使用相同Item 实例化的MultiStack;好消息是,现在编译器可以确定这两个 Item 类型是相同的,所以不会出现类型冲突。

要实例化,使用与上面相同的 Inst 示例:

package Inst is new MultiStack (Item => Some_Type, Put => Some_Put_Procedure);
package StackMove_Inst is new StackMove (Item => Some_Type, Stack_Instance => Inst);

【以上两个不一定要这样在一起;它们可以在不同的包中。]

【讨论】:

  • 我尝试了类似的方法,但仍然得到invalid prefix in selected component "MultiStack"。我已经更新了我的问题。
  • @DaWood 你没有说它是通用的——它改变了很多东西。
猜你喜欢
  • 1970-01-01
  • 2019-11-14
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
相关资源
最近更新 更多