通用链表的问题

Trouble with generic linked list

我正在学习 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

我能理解其他错误告诉我的内容。

编辑:我修复了部分代码并收到了新的错误消息,所有内容都已更新。

包本质上是命名空间,而不是 类。因此,您不能创建该包的对象(实例),它不导出任何类型。

因此,您声明的东西更像是一个单例:在您的例子中,只能有一个(每个通用实例化),称为 List。 并且 List 导出了你可以使用的子程序。

所以删除声明 lst : List; 并直接调用子程序,List.Add_Element(i); 你的例子应该可以工作。

如果您需要更多链表,您可以根据需要多次实例化泛型。您在每次调用中使用的列表由实例化的包名称确定。


如果要创建包中声明的类型的对象,则必须在包中声明该类型;您只需在 public 部分添加行 type Node is private; 即可;虽然 type Node_Acc is access node; 通常也很有用 - 然后将 Beginning,Last 的声明更新为这种类型。

那么每个子程序都需要知道自己操作的是哪个Node;所以他们需要一个 Node 作为参数,例如 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);