2012-05-07 50 views
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; 

也許有另一種方式做到這一點,因爲我覺得它使用子包是不可能的......

+1

我有一個回答(http://stackoverflow.com/a/10515906/40851)在回答你的其他問題..使用兄弟軟件包而不是子包。 –

回答

1

在一般情況下,沒有;第二個示例的工作原理是Child的規範在​​Parent中聲明F時已知。根據您關於此主題的previous question,可能需要一種乾淨的方法來分隔公共規範的多個實現。這個相關的Q&A討論了兩種方法:一種使用繼承,另一種在編譯時使用基於庫的機制。

+0

所以我唯一的解決方案是使我的軟件包的類型作爲模板的參數通用... –

+0

我會推遲到更有知識的參與者,但我不認爲有足夠的信息來說這是你的_only_解決方案。如果繼承不合適,則可以在編譯時提供子體。現在得走。 – trashgod

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; 

是OK的編譯,但如果你與父規範孩子記得(就像你對F的參數做的那樣),你會得到一個循環依賴關係,因爲孩子需要他們的父母先存在!

因此它實際上取決於你想成爲公衆孩子,這是否是一個實際的解決您的問題是什麼

+0

事情是我真的需要在一個單獨的文件中包含Child包,並且它包含的內容必須是透明的以便在父包中使用。這就是爲什麼我正在尋找一個包含子包的解決方案:它可以包含聲明,並且可以在單獨的文件中;而不可能在類型聲明中使用'separate'。所以我仍然有同樣的問題:我需要分開類型聲明。 –

+0

@JulioGuerra是否有必要在parent.child heirachy中的某個地方進行類型聲明?如果沒有,爲什麼不把類型聲明放在parent_types.ads中,並將這個文件放在parent.ads&parent.child.ads中? – NWS

+0

這是不可能的:「'''只能出現在上下文子句中」,它在包之外。 –

1

胡里奧,在規範文件中聲明的類型(mytypes.ads)

package Mytypes is 

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

end Mytypes; 

... 在其他幾個Withed它:

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 

這是你嘗試過什麼?

+0

你不必寫一個完整的例子:)所以你把類型放在一個包中,這是一個編譯單元。是的,它的工作原理,但是對我來說有一個語義/邏輯問題:這些類型屬於Parent包,邏輯是將它們放在這個包中,這到目前爲止是不可能的(與分離):( –