Ada 如何使用泛型类型?
我在这里学习这个例子: 我已经编写了我的Ada 如何使用泛型类型?,ada,ada95,Ada,Ada95,我在这里学习这个例子: 我已经编写了我的通用\u堆栈。ads: generic type Item_Type is private; size : Positive; package Generic_Stack is procedure push( item : in Item_Type ); function pop return Item_Type; function is_Empty return Boolean; STACK_E
通用\u堆栈。ads
:
generic
type Item_Type is private;
size : Positive;
package Generic_Stack is
procedure push( item : in Item_Type );
function pop return Item_Type;
function is_Empty return Boolean;
STACK_EMPTY : exception;
STACK_FULL : exception;
end Generic_Stack;
和我的通用堆栈.adb
:
package body Generic_Stack
is
type Stack_Table is array (Positive range <>) of Item_Type;
nodes : Stack_Table( 1..size );
index : Natural := 0;
procedure push( item : in Item_Type )
is
begin
if ( index < size )
then
index := index + 1;
nodes(index) := item;
else
raise STACK_FULL;
end if;
end push;
function pop()
return
Item_Type
is
item : Item_Type;
begin
if ( index > 0 )
then
item := nodes( index );
index := index - 1;
else
raise STACK_EMPTY;
end if;
return item;
end pop;
-- function is_Empty() removed for the sake of brevity
end Generic_Stack;
Gnat给了我编译错误:
# gnat make -gnat95 generic_stack_test.adb -o generic_stack_test
x86_64-linux-gnu-gcc-8 -c -gnat95 generic_stack_test.adb
generic_stack_test.adb:9:08: keyword "body" expected here [see file name]
generic_stack_test.adb:20:24: missing "end Stack_Int_Type;"
x86_64-linux-gnu-gnatmake-8: "generic_stack_test.adb" compilation error
我必须声明堆栈类型或类似的类型吗?我不明白如何在过程中使用declare。如果我将一个Stack\u Int\u Type
传递给另一个过程,它是否也必须声明该类型
是否可以在.ads
中简单地声明一次Stack\u Int\u Type
,并将其用作常规类型?我的书和网页有点建议每次都必须声明它,这听起来很繁重。您的通用堆栈包从未定义堆栈数据类型。
Push和Pop过程是堆栈上的操作。您必须有一个要操作的类型。堆栈有两大类;有界堆栈和无界堆栈。您必须决定要创建哪种类型的堆栈。
有关Ada中实现的两种堆栈的讨论,请参见
在上面URL中引用的示例中,您将看到如何创建可多次使用的堆栈类型。Adahome的例子是一个古老而有问题的例子。您已经确定了最大的问题。您的通用\u堆栈包从未定义堆栈数据类型。
Push和Pop过程是堆栈上的操作。您必须有一个要操作的类型。堆栈有两大类;有界堆栈和无界堆栈。您必须决定要创建哪种类型的堆栈。
有关Ada中实现的两种堆栈的讨论,请参见
在上面URL中引用的示例中,您将看到如何创建可多次使用的堆栈类型。Adahome的例子是一个古老而有问题的例子。您已经确定了最大的问题。您的测试代码实际上是两个库项:
与通用_堆栈;
包堆栈_Int_Type是新的泛型_堆栈(Item_Type=>Integer,Size=>32);
声明库包Stack\u Int\u Type
,以及
程序通用\u堆栈\u测试
是
堆栈:堆栈类型;
开始
堆栈推送(3);
结束一般的堆栈测试;
声明一个库过程,目前它对Stack\u Int\u Type
一无所知
我们可以通过使用
添加必要的,但是(使用-gnatl
编译)来解决这个问题
这里发生的事情是,Generic\u Stack
没有声明类型,因此不能在第4行声明它的实例;这是一种单身。(除其他事项外,这意味着它的名称令人困惑:我会将其称为Integer\u Stack
。可能永远不要调用包\u Type
;\u Types
)
解决这个问题,
与通用_堆栈;
包整数\u堆栈是新的通用\u堆栈(项类型=>Integer,大小=>32);
及
具有整数_堆栈;
程序通用\u堆栈\u测试
是
开始
整数栈推(3);
结束一般的堆栈测试;
您可以将Integer\u堆栈设置为本地:
与通用_堆栈;
程序通用\u堆栈\u测试
是
包整数栈
是新的泛型_堆栈(Item_Type=>Integer,Size=>32);
开始
整数栈推(3);
结束一般的堆栈测试;
您的测试代码实际上是两个库项:
与通用_堆栈;
包堆栈_Int_Type是新的泛型_堆栈(Item_Type=>Integer,Size=>32);
声明库包Stack\u Int\u Type
,以及
程序通用\u堆栈\u测试
是
堆栈:堆栈类型;
开始
堆栈推送(3);
结束一般的堆栈测试;
声明一个库过程,目前它对Stack\u Int\u Type
一无所知
我们可以通过使用
添加必要的,但是(使用-gnatl
编译)来解决这个问题
这里发生的事情是,Generic\u Stack
没有声明类型,因此不能在第4行声明它的实例;这是一种单身。(除其他事项外,这意味着它的名称令人困惑:我会将其称为Integer\u Stack
。可能永远不要调用包\u Type
;\u Types
)
解决这个问题,
与通用_堆栈;
包整数\u堆栈是新的通用\u堆栈(项类型=>Integer,大小=>32);
及
具有整数_堆栈;
程序通用\u堆栈\u测试
是
开始
整数栈推(3);
结束一般的堆栈测试;
您可以将Integer\u堆栈设置为本地:
与通用_堆栈;
程序通用\u堆栈\u测试
是
包整数栈
是新的泛型_堆栈(Item_Type=>Integer,Size=>32);
开始
整数栈推(3);
结束一般的堆栈测试;
如其他地方所述,您的软件包规范没有定义任何类型。否则,您将有类型。。。在包
关键字之后的某个地方。就这么简单
但正如其他地方所解释的,这并不戏剧性。您的包实例化将准确地定义一个堆栈,而不是在多个位置使用的类型。在某些情况下,这正是你所需要的。因此,您可以调用实例化的包My_Stack
,它实际上围绕一个对象进行表达(My_Stack.nodes
,只能通过Push
和Pop
访问)
您需要从一个单元(过程、包等)内实例化通用_堆栈。除此之外,它是“外层空间”,只有with
和use
子句需要与其他单元连接
with Generic_Stack;
procedure Generic_Stack_Test
is
package My_Stack is new Generic_Stack( Item_Type => Integer, Size => 32 );
begin
My_Stack.push( 3 );
end Generic_Stack_Test;
正如其他地方所解释的,包规范没有定义任何类型。否则,您将有类型。。。在包
关键字之后的某个地方。就这么简单
但正如其他地方所解释的,这并不戏剧性。您的包实例化将准确地定义一个堆栈,一个
1. with Stack_Int_Type;
2. procedure Generic_Stack_Test
3. is
4. stack : Stack_Int_Type;
|
>>> subtype mark required in this context
>>> found "Stack_Int_Type" declared at stack_int_type.ads:2
5. begin
6. stack.push( 3 );
1 2
>>> invalid prefix in selected component "stack"
>>> prefixed call is only allowed for objects of a tagged type
7. end Generic_Stack_Test;
with Generic_Stack;
procedure Generic_Stack_Test
is
package My_Stack is new Generic_Stack( Item_Type => Integer, Size => 32 );
begin
My_Stack.push( 3 );
end Generic_Stack_Test;