如何使用泛型?

金斯利

我正在这里处理示例:https : //www.adahome.com/rm95/rm9x-12-08.html

我写了我的generic_stack.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;

而我的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;

我不太了解如何实际使用Generic_Stack
用简单的generic_stack_test.adb代码:

with Generic_Stack;
package Stack_Int_Type is new Generic_Stack( Item_Type => Integer, Size => 32 );

procedure Generic_Stack_Test
is
    stack : Stack_Int_Type;
begin
    stack.push( 3 );
end Generic_Stack_Test;

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_Int_Type吗?我不明白如何在过程中使用声明。如果我将a传递Stack_Int_Type给另一个过程,它也必须声明类型吗?

是否有可能只是宣布Stack_Int_Type 一次在一个.ads,并把它作为一个普通类型?我的书和网页建议每次都必须声明它,这听起来很麻烦。

西蒙·赖特

您的测试代码实际上是两个库项目:

with Generic_Stack;
package Stack_Int_Type is new Generic_Stack( Item_Type => Integer, Size => 32 );

声明一个库包Stack_Int_Type,并且

procedure Generic_Stack_Test
is
    stack : Stack_Int_Type;
begin
    stack.push( 3 );
end Generic_Stack_Test;

声明一个库程序,就目前而言,该程序不了解Stack_Int_Type
我们可以通过添加必要的来解决此问题with,但是(使用编译-gnatl

 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;

这里发生的是Generic_Stack没有声明类型,因此您不能在第4行声明它的实例。这是一种单例。(在其他事情中,这意味着它的名称容易混淆:我已经将其命名Integer_Stack。可能从不调用package _Type_Types也许。)

with Generic_Stack;
package Integer_Stack is new Generic_Stack( Item_Type => Integer, Size => 32 );

with Integer_Stack;
procedure Generic_Stack_Test
is
begin
   Integer_Stack.push( 3 );
end Generic_Stack_Test;

您可以将其设置为Integer_Stack本地:

with Generic_Stack;
procedure Generic_Stack_Test
is
   package Integer_Stack
   is new Generic_Stack( Item_Type => Integer, Size => 32 );
begin
   Integer_Stack.push( 3 );
end Generic_Stack_Test;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章