3

是否可以从父包访问子包声明?

-- parent.ads
package Parent is
   procedure F(A : Child_Type);
end Parent;

-- parent-child.ads
package Parent.Child is
   type Child_Type is (A, B, C);
end Parent.Child;

嵌套版本工作正常:

-- parent.ads
package Parent is
   package Child is
      type Child_Type is (A, B, C);
   end Child;
   use Child;

   procedure F(A : Child_Type);
end Parent;

也许还有另一种方法可以做到这一点,因为我认为使用子包是不可能的......

4

3 回答 3

1

一般来说,没有;第二个示例有效,因为 的规范在中声明Child时是已知的。根据您之前关于此主题的问题,您可能想要一种干净的方法来分离通用规范的多个实现。这个相关的问答讨论了两种方法:一种使用继承,另一种在编译时使用基于库的机制。FParent

于 2012-05-07T11:09:34.710 回答
1

我认为您正在寻找的是一个private子包,这通常与您的嵌套示例的行为方式相同,但您无法在其父主体之外访问它。

所以 :

private package Parent.Child is
   type Child_Type is (A,B,C);
end Parent.Child;

...

package Parent is
   procedure F;
end Parent;

...

with Ada.Text_Io;
with Parent.Child;
package body Parent is
   procedure F is
   begin
      for A in Parent.Child.Child_Type'Range loop
         Ada.Text_Io.Put_Line (Parent.Child.Child_Type'Image (A));
      end loop;
   end F;
end Parent;

可以编译,但请记住,如果您在父规范中使用孩子(就像您使用参数 to 一样F),您将获得循环依赖,因为孩子需要他们的父母首先存在!

因此,这实际上取决于您想向父母和孩子公开什么,是否是您问题的实际解决方案。

于 2012-05-08T07:38:56.540 回答
1

Julio,在规范文件 (mytypes.ads) 中声明的类型

package Mytypes is

   type Fruit is (Apple, Pear, Pineapple, Banana, Poison_Apple);
   subtype Safe_Fruit is Fruit range Apple .. Banana;

end Mytypes;

...在其他几个中使用它:

with Mytypes;
package Parent is

   function Permission (F : in Mytypes.Fruit) return Boolean;

end Parent;

...

package body Parent is

   function Permission (F : in Mytypes.Fruit) return Boolean is
   begin
      return F in Mytypes.Safe_Fruit;
   end Permission;

end Parent;

...

package Parent.Child is

   procedure Eat (F : in Mytypes.Fruit);

end Parent.Child;

...

with Ada.Text_Io;
package body Parent.Child is

   procedure Eat (F : in Mytypes.Fruit) is
   begin
      if Parent.Permission (F) then
         Ada.Text_Io.Put_Line ("Eating " & Mytypes.Fruit'Image (F));
      else
         Ada.Text_Io.Put_Line ("Forbidden to eat " & Mytypes.Fruit'Image (F));
      end if;
   end Eat;

end Parent.Child;

...

with Mytypes;
with Parent.Child;

procedure Main is

begin

   for I in Mytypes.Fruit'Range loop
      Parent.Child.Eat (I);
   end loop;

end Main;

它编译:

$ gnatmake main.adb
gcc-4.4 -c parent-child.adb
gnatbind -x main.ali
gnatlink main.ali

它运行:

$ ./main
Eating APPLE
Eating PEAR
Eating PINEAPPLE
Eating BANANA
Forbidden to eat POISON_APPLE

这是你试过的吗?

于 2012-05-10T14:34:15.330 回答