访问子包声明

时间:2012-05-07 09:48:46

标签: packaging ada

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

-- 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;

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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;

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

因此,它真的取决于你想要公开的 孩子是否这是你的实际解决方案问题

答案 2 :(得分:1)

Julio,在spec文件(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

这是你试过的吗?