2016-03-09 50 views
0

我正在學習Ada中的泛型,所以我實現了一個簡單的鏈表。這裏是我的代碼:通用鏈接列表的問題

Linked_List.adb : 
    package body Linked_List is 
    function Get_First_Element return Element_Type is 
    begin 
     return Beginning.Value; 
    end Get_First_Element; 

    function Get_Last_Element return Element_Type is 
     temp : Node := Beginning.all; 
    begin 
     while temp.Next /= null loop 
     temp := temp.Next.all; 
     end loop; 
     return temp.Value; 
    end Get_Last_Element; 

    procedure Add_Element(data : Element_Type) is 
     newNode : access Node; 
    begin 
     newNode := new Node; 
     newNode.all.Value := data; 
     if Beginning.all.Next = null then 
     Beginning := newNode; 
     else 
     Last.Next := newNode; 
     Last := newNode; 
     end if; 

    end Add_Element; 

    procedure Remove_Element(data : Element_Type) is 
     temp : access Node := Beginning; 
     prev : Node; 
    begin 
     while temp /= null or temp.all.Value /= data loop 
     prev := temp.all; 
     temp := temp.Next; 
     end loop; 
     if temp = null then 
     return; 
     else 
     prev.Next := temp.all.Next; 
     end if; 
    end Remove_Element; 

    function Exists(data : Element_Type) return Boolean is 
     temp : access Node := Beginning; 
    begin 
     while temp /= null or temp.all.Value /= data loop 
     temp := temp.Next; 
     end loop; 
     if temp = null then 
     return false; 
     end if; 
     return true; 
    end Exists; 
begin 
    Beginning.all.Next := Last; 
end Linked_List; 

Linked_List.ads:

generic 
    type Element_Type is private; 
package Linked_List is 
    function Get_First_Element return Element_Type; 
    function Get_Last_Element return Element_Type; 
    procedure Add_Element(data : Element_Type); 
    procedure Remove_Element(data : Element_Type); 
    function Exists(data : Element_Type) return Boolean; 
private 
    type Node is 
     record 
      Value : Element_Type; 
      Next : access Node; 
     end record; 
    Beginning : access Node; 
    Last : access Node; 
end Linked_List; 

請問兩個文件編譯的罰款。這是我的主要程序:

With Ada.Text_IO; use Ada.Text_IO; 
with Linked_List; 
procedure Main is 
    package List is new Linked_List(Element_Type => Integer); 
    lst : List; 
begin 

    for i in -5..5 loop 
     lst.Add_Element(i); 
    end loop; 
    lst.Remove_Element(1); 
    Put_Line(lst.Exists(2)); 
end Main; 

這就是我面臨的一個問題。以下是該編譯器是給我的錯誤:

main.adb:5:10: subtype mark required in this context 
main.adb:5:10: found "List" declared at line 4 
main.adb:5:14: incorrect constraint for this kind of type 
main.adb:9:07: invalid prefix in selected component "lst" 
main.adb:11:04: invalid prefix in selected component "lst" 
main.adb:12:13: invalid prefix in selected component "lst" 

我無法理解這樣的錯誤:

main.adb:5:10: subtype mark required in this context 

我能理解什麼其他錯誤,告訴我。

編輯:我固定的代碼的一部分,我得到了新的錯誤消息,一切都將被更新。

回答

1

包基本上是命名空間,而不是類。因此,您不能創建該包的對象(實例),該對象不會導出任何類型。

所以,你必須聲明的是東西,而像單:只能有它的一個(每個泛型實例),你的情況,所謂的名單。 並列出您可以使用的子程序。

因此,刪除聲明lst : List;並直接調用子程序,List.Add_Element(i);和您的示例應該工作。

如果您需要更多的鏈接列表,您可以根據需要實例化通用多次。您在每次調用中使用的列表由實例化的包名稱確定。


如果您想創建包中聲明的類型的對象,您必須在包中聲明類型;在公共部分添加行type Node is private;是您所需要做的;儘管type Node_Acc is access node;通常也很有用 - 然後將Beginning,Last的聲明更新爲此類型。

然後每個子程序需要知道它們運行在哪個節點;所以他們需要一個節點作爲參數,例如function Get_First_Element(this : Node) return Element_Type;

現在,你可以聲明Node類型的對象,並將它們作爲參數傳遞。 如果記錄是帶標記的記錄,則可以使用function(argument)object.method表示法,以使程序更易於理解。

-- package 
type Node is tagged private; 
private 
type Node is tagged record ...; 

-- client code 
    Head : List.Node; 
    ... 
    Add_Element(Head,1); 
    Head.Add_Element(2);