通用链表的问题
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);
我正在学习 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);