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;